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
8.65M
#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
51.8k
#define BEGIN_SIGNATURE 2
83
77.1k
#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
12.8k
{
116
12.8k
  armor_filter_context_t *afx;
117
12.8k
  gpg_error_t err;
118
119
12.8k
  afx = xcalloc (1, sizeof *afx);
120
12.8k
  if (afx)
121
12.8k
    {
122
12.8k
      err = gcry_md_open (&afx->crc_md, GCRY_MD_CRC24_RFC2440, 0);
123
12.8k
      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
12.8k
      afx->refcount = 1;
132
12.8k
    }
133
134
12.8k
  return afx;
135
12.8k
}
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
59.5k
{
142
59.5k
  if (!afx)
143
33.8k
    return;
144
25.6k
  log_assert (afx->refcount);
145
25.6k
  if ( --afx->refcount )
146
12.8k
    return;
147
12.8k
  gcry_md_close (afx->crc_md);
148
12.8k
  xfree (afx);
149
12.8k
}
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
12.8k
{
155
12.8k
  int rc;
156
157
12.8k
  afx->refcount++;
158
12.8k
  rc = iobuf_push_filter (iobuf, armor_filter, afx);
159
12.8k
  if (rc)
160
0
    afx->refcount--;
161
12.8k
  return rc;
162
12.8k
}
163
164
165
166
167
168
static void
169
initialize(void)
170
4
{
171
4
    u32 i;
172
4
    const byte *s;
173
174
    /* Build the helptable for radix64 to bin conversion.  Value 0xffffffff is
175
       used to detect invalid characters.  */
176
4
    memset (asctobin, 0xff, sizeof(asctobin));
177
260
    for(s=bintoasc,i=0; *s; s++,i++ )
178
256
      {
179
256
  asctobin[0][*s] = i << (0 * 6);
180
256
  asctobin[1][*s] = i << (1 * 6);
181
256
  asctobin[2][*s] = i << (2 * 6);
182
256
  asctobin[3][*s] = i << (3 * 6);
183
256
      }
184
185
4
    is_initialized=1;
186
4
}
187
188
189
static inline u32
190
get_afx_crc (armor_filter_context_t *afx)
191
2.70k
{
192
2.70k
  const byte *crc_buf;
193
2.70k
  u32 crc;
194
195
2.70k
  crc_buf = gcry_md_read (afx->crc_md, GCRY_MD_CRC24_RFC2440);
196
197
2.70k
  crc = crc_buf[0];
198
2.70k
  crc <<= 8;
199
2.70k
  crc |= crc_buf[1];
200
2.70k
  crc <<= 8;
201
2.70k
  crc |= crc_buf[2];
202
203
2.70k
  return crc;
204
2.70k
}
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
126k
{
219
126k
  int ctb, pkttype;
220
126k
  int indeterminate_length_allowed;
221
222
126k
    ctb = *buf;
223
126k
    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
78.5k
      return 1;
228
229
48.2k
    pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
230
48.2k
    switch( pkttype ) {
231
1.54k
      case PKT_PUBKEY_ENC:
232
12.1k
      case PKT_SIGNATURE:
233
13.4k
      case PKT_SYMKEY_ENC:
234
14.7k
      case PKT_ONEPASS_SIG:
235
15.5k
      case PKT_SECRET_KEY:
236
20.8k
      case PKT_PUBLIC_KEY:
237
22.9k
      case PKT_SECRET_SUBKEY:
238
23.5k
      case PKT_MARKER:
239
25.8k
      case PKT_RING_TRUST:
240
26.7k
      case PKT_USER_ID:
241
27.4k
      case PKT_PUBLIC_SUBKEY:
242
29.2k
      case PKT_ATTRIBUTE:
243
30.5k
      case PKT_MDC:
244
30.5k
  indeterminate_length_allowed = 0;
245
30.5k
        break;
246
247
5.97k
      case PKT_COMPRESSED:
248
6.95k
      case PKT_ENCRYPTED:
249
7.92k
      case PKT_ENCRYPTED_MDC:
250
8.32k
      case PKT_ENCRYPTED_AEAD:
251
12.2k
      case PKT_PLAINTEXT:
252
12.6k
      case PKT_OLD_COMMENT:
253
12.9k
      case PKT_COMMENT:
254
13.8k
      case PKT_GPG_CONTROL:
255
13.8k
  indeterminate_length_allowed = 1;
256
13.8k
        break;
257
258
3.91k
      default:
259
        /* Invalid packet type.  */
260
3.91k
        return 1;
261
48.2k
    }
262
263
44.3k
    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
30.5k
      {
269
30.5k
        int new_format;
270
30.5k
        int indeterminate_length;
271
272
30.5k
        new_format = !! (ctb & (1 << 6));
273
30.5k
        if (new_format)
274
11.5k
          indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
275
18.9k
        else
276
18.9k
          indeterminate_length = (ctb & 3) == 3;
277
278
30.5k
        if (indeterminate_length)
279
2.43k
          return 1;
280
30.5k
      }
281
282
    /* The first CTB seems legit.  It is probably not armored
283
       data.  */
284
41.9k
    return 0;
285
44.3k
}
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
53.4k
{
296
53.4k
    byte buf[2];
297
53.4k
    int n;
298
299
    /* fixme: there might be a problem with iobuf_peek */
300
53.4k
    n = iobuf_peek (a, buf, 2);
301
53.4k
    if( n == -1 )
302
0
  return 0; /* EOF, doesn't matter whether armored or not */
303
53.4k
    if( !n )
304
0
  return 1; /* can't check it: try armored */
305
53.4k
    if (n != 2)
306
125
  return 0; /* short buffer */
307
53.2k
    return is_armored(buf);
308
53.4k
}
309
310
311
312
313
static void
314
invalid_armor(void)
315
31.6k
{
316
31.6k
    write_status(STATUS_BADARMOR);
317
#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
318
    g10_exit(1); /* stop here */
319
#endif
320
31.6k
}
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
13.7k
{
333
13.7k
    const char *s, *s2;
334
13.7k
    unsigned found = 0;
335
336
13.7k
    if( strlen(line) < 6  || strlen(line) > 60 )
337
1.79k
  return 0; /* too short or too long */
338
11.9k
    if( memcmp( line, "Hash:", 5 ) )
339
2.05k
  return 0; /* invalid header */
340
341
16.9k
    for(s=line+5;;s=s2) {
342
27.5k
  for(; *s && (*s==' ' || *s == '\t'); s++ )
343
10.5k
      ;
344
16.9k
  if( !*s )
345
4.32k
      break;
346
42.7k
  for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
347
30.0k
      ;
348
12.6k
  if( !strncmp( s, "RIPEMD160", s2-s ) )
349
1.15k
      found |= 1;
350
11.5k
  else if( !strncmp( s, "SHA1", s2-s ) )
351
5.87k
      found |= 2;
352
5.63k
  else if( !strncmp( s, "SHA224", s2-s ) )
353
1.20k
      found |= 8;
354
4.42k
  else if( !strncmp( s, "SHA256", s2-s ) )
355
567
      found |= 16;
356
3.86k
  else if( !strncmp( s, "SHA384", s2-s ) )
357
636
      found |= 32;
358
3.22k
  else if( !strncmp( s, "SHA512", s2-s ) )
359
951
      found |= 64;
360
2.27k
  else
361
2.27k
      return 0;
362
15.3k
  for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
363
5.00k
      ;
364
10.3k
  if( *s2 && *s2 != ',' )
365
3.30k
      return 0;
366
7.08k
  if( *s2 )
367
2.86k
      s2++;
368
7.08k
    }
369
4.32k
    return found;
370
9.89k
}
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
8.81k
{
376
8.81k
  if(strncmp(line,"Version",7)==0
377
8.81k
     || strncmp(line,"Comment",7)==0
378
8.81k
     || strncmp(line,"MessageID",9)==0
379
8.81k
     || strncmp(line,"Hash",4)==0
380
8.81k
     || strncmp(line,"Charset",7)==0)
381
3.65k
    return 1;
382
383
5.16k
  return 0;
384
8.81k
}
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.33M
{
394
3.33M
    const char *s;
395
3.33M
    byte *save_p, *p;
396
3.33M
    int save_c;
397
3.33M
    int i;
398
399
3.33M
    if( len < 15 )
400
3.13M
  return -1; /* too short */
401
208k
    if( memcmp( line, "-----", 5 ) )
402
95.7k
  return -1; /* no */
403
112k
    p = strstr( line+5, "-----");
404
112k
    if( !p )
405
17.0k
  return -1;
406
95.6k
    save_p = p;
407
95.6k
    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
95.6k
    if(RFC2440)
418
0
      {
419
0
  if( *p == '\r' )
420
0
    p++;
421
0
  if( *p == '\n' )
422
0
    p++;
423
0
      }
424
95.6k
    else
425
190k
      while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
426
95.3k
  p++;
427
428
95.6k
    if( *p )
429
2.04k
  return -1; /* garbage after dashes */
430
93.6k
    save_c = *save_p; *save_p = 0;
431
93.6k
    p = line+5;
432
362k
    for(i=0; (s=head_strings[i]); i++ )
433
349k
  if( !strcmp(s, p) )
434
80.8k
      break;
435
93.6k
    *save_p = save_c;
436
93.6k
    if (!s)
437
12.7k
      {
438
12.7k
        if (!strncmp (p, "BEGIN ", 6))
439
7.78k
          return 42;
440
5.01k
  return -1; /* unknown armor line */
441
12.7k
      }
442
443
80.8k
    if( opt.verbose > 1 )
444
0
  log_info(_("armor: %s\n"), head_strings[i]);
445
80.8k
    return i;
446
93.6k
}
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
137k
{
459
137k
    byte *p;
460
137k
    int hashes=0;
461
137k
    unsigned int len2;
462
463
137k
    len2 = length_sans_trailing_ws ( line, len );
464
137k
    if( !len2 ) {
465
52.6k
        afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
466
52.6k
  return 0; /* WS only: same as empty line */
467
52.6k
    }
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
84.3k
    p = strchr( line, ':');
480
84.3k
    if (!p && afx->dearmor_state)
481
0
      return 0; /* Special treatment in --dearmor mode.  */
482
84.3k
    if( !p || (RFC2440 && p[1]!=' ')
483
84.3k
  || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
484
61.7k
      {
485
61.7k
  log_error (_("invalid armor header: "));
486
61.7k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
487
61.7k
  log_printf ("\n");
488
61.7k
  return -1;
489
61.7k
      }
490
491
    /* Chop off the whitespace we detected before */
492
22.5k
    len=len2;
493
22.5k
    line[len2]='\0';
494
495
22.5k
    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
22.5k
    if (afx->dearmor_mode)
502
0
      ;
503
22.5k
    else if (afx->in_cleartext)
504
13.7k
      {
505
13.7k
  if( (hashes=parse_hash_header( line )) )
506
4.32k
    afx->hashes |= hashes;
507
9.42k
  else if( strlen(line) > 15 && !memcmp( line, "NotDashEscaped:", 15 ) )
508
1.33k
    afx->not_dash_escaped = 1;
509
8.09k
  else
510
8.09k
    {
511
8.09k
      log_error(_("invalid clearsig header\n"));
512
8.09k
      return -1;
513
8.09k
    }
514
13.7k
      }
515
8.81k
    else if(!is_armor_tag(line))
516
5.16k
      {
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
5.16k
  log_info(_("unknown armor header: "));
525
5.16k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
526
5.16k
  log_printf ("\n");
527
5.16k
      }
528
529
14.4k
    return 1;
530
22.5k
}
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
81.4k
{
538
81.4k
    int rc = 0;
539
81.4k
    int i;
540
81.4k
    byte *line;
541
81.4k
    unsigned len;
542
81.4k
    unsigned maxlen;
543
81.4k
    int hdr_line = -1;
544
545
    /* read the first line to see whether this is armored data */
546
81.4k
    maxlen = MAX_LINELEN;
547
81.4k
    len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
548
81.4k
               &afx->buffer_size, &maxlen );
549
81.4k
    line = afx->buffer;
550
81.4k
    if( !maxlen ) {
551
  /* line has been truncated: assume not armored */
552
140
  afx->inp_checked = 1;
553
140
  afx->inp_bypass = 1;
554
140
  return 0;
555
140
    }
556
557
81.2k
    if( !len ) {
558
291
  return -1; /* eof */
559
291
    }
560
561
    /* (the line is always a C string but maybe longer) */
562
80.9k
    if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
563
7.37k
  ;
564
73.6k
    else if (len >= 2 && !is_armored (line)) {
565
1.41k
  afx->inp_checked = 1;
566
1.41k
  afx->inp_bypass = 1;
567
1.41k
  return 0;
568
1.41k
    }
569
570
    /* find the armor header */
571
3.29M
    while(len) {
572
3.28M
  i = is_armor_header( line, len );
573
3.28M
        if ( i == 42 ) {
574
5.42k
            if (afx->dearmor_mode) {
575
0
                afx->dearmor_state = 1;
576
0
                break;
577
0
            }
578
5.42k
        }
579
3.28M
        else if (i >= 0
580
3.28M
                 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
581
77.1k
      hdr_line = i;
582
77.1k
      if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
583
48.9k
          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
48.9k
    afx->in_cleartext = 1;
588
48.9k
      }
589
77.1k
      break;
590
77.1k
  }
591
592
  /* read the next line (skip all truncated lines) */
593
3.21M
  do {
594
3.21M
      maxlen = MAX_LINELEN;
595
3.21M
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
596
3.21M
                 &afx->buffer_size, &maxlen );
597
3.21M
      line = afx->buffer;
598
3.21M
      len = afx->buffer_len;
599
3.21M
  } while( !maxlen );
600
3.21M
    }
601
602
    /* Parse the header lines.  */
603
91.9k
    while(len) {
604
  /* Read the next line (skip all truncated lines). */
605
89.6k
  do {
606
89.6k
      maxlen = MAX_LINELEN;
607
89.6k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
608
89.6k
                 &afx->buffer_size, &maxlen );
609
89.6k
      line = afx->buffer;
610
89.6k
      len = afx->buffer_len;
611
89.6k
  } while( !maxlen );
612
613
89.5k
  i = parse_header_line( afx, line, len );
614
89.5k
  if( i <= 0 ) {
615
77.1k
      if (i && RFC2440)
616
0
    rc = GPG_ERR_INV_ARMOR;
617
77.1k
      break;
618
77.1k
  }
619
89.5k
    }
620
621
622
79.5k
    if( rc )
623
0
  invalid_armor();
624
79.5k
    else if( afx->in_cleartext )
625
48.9k
  afx->faked = 1;
626
30.6k
    else {
627
30.6k
  afx->inp_checked = 1;
628
30.6k
  gcry_md_reset (afx->crc_md);
629
30.6k
  afx->idx = 0;
630
30.6k
  afx->radbuf[0] = 0;
631
30.6k
    }
632
633
79.5k
    return rc;
634
80.9k
}
635
636
62.2M
#define PARTIAL_CHUNK 512
637
31.4k
#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
50.3k
{
648
50.3k
    int rc = 0;
649
50.3k
    size_t len = 0;
650
50.3k
    int lastline = 0;
651
50.3k
    unsigned maxlen, n;
652
50.3k
    byte *p;
653
50.3k
    byte tempbuf[PARTIAL_CHUNK];
654
50.3k
    size_t tempbuf_len=0;
655
50.3k
    int this_truncated;
656
657
5.17M
    while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
658
  /* copy what we have in the line buffer */
659
5.12M
  if( afx->faked == 1 )
660
48.9k
      afx->faked++; /* skip the first (empty) line */
661
5.07M
  else
662
5.07M
    {
663
      /* It's full, so write this partial chunk */
664
5.07M
      if(tempbuf_len==PARTIAL_CHUNK)
665
31.4k
        {
666
31.4k
    buf[len++]=0xE0+PARTIAL_POW;
667
31.4k
    memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
668
31.4k
    len+=PARTIAL_CHUNK;
669
31.4k
    tempbuf_len=0;
670
31.4k
    continue;
671
31.4k
        }
672
673
23.3M
      while( tempbuf_len < PARTIAL_CHUNK
674
23.3M
       && afx->buffer_pos < afx->buffer_len )
675
18.3M
        tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
676
5.04M
      if( tempbuf_len==PARTIAL_CHUNK )
677
31.4k
        continue;
678
5.04M
    }
679
680
  /* read the next line */
681
5.05M
  maxlen = MAX_LINELEN;
682
5.05M
  afx->buffer_pos = 0;
683
5.05M
  afx->buffer_len = iobuf_read_line( a, &afx->buffer,
684
5.05M
             &afx->buffer_size, &maxlen );
685
5.05M
  if( !afx->buffer_len ) {
686
2.76k
      rc = -1; /* eof (should not happen) */
687
2.76k
      continue;
688
2.76k
  }
689
5.05M
  if( !maxlen )
690
158
          {
691
158
      afx->truncated++;
692
158
            this_truncated = 1;
693
158
          }
694
5.05M
        else
695
5.05M
          this_truncated = 0;
696
697
698
5.05M
  p = afx->buffer;
699
5.05M
  n = afx->buffer_len;
700
701
  /* Armor header or dash-escaped line? */
702
5.05M
  if(p[0]=='-')
703
66.9k
    {
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
66.9k
      if(p[1]==' ' && !afx->not_dash_escaped)
711
800
        {
712
    /* It's a dash-escaped line, so skip over the
713
       escape. */
714
800
    afx->buffer_pos = 2;
715
800
        }
716
66.1k
      else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
717
50.5k
        {
718
    /* Five dashes in a row mean it's probably armor
719
       header. */
720
50.5k
    int type = is_armor_header( p, n );
721
50.5k
                if (type == 42)
722
2.35k
                  type = -1;  /* Only OpenPGP armors are expected.  */
723
50.5k
    if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
724
4.38k
      ; /* this is okay */
725
46.1k
    else
726
46.1k
      {
727
46.1k
        if( type != BEGIN_SIGNATURE )
728
44.4k
          {
729
44.4k
      log_info(_("unexpected armor: "));
730
44.4k
      es_write_sanitized (log_get_stream (), p, n,
731
44.4k
                                            NULL, NULL);
732
44.4k
      log_printf ("\n");
733
44.4k
          }
734
735
46.1k
        lastline = 1;
736
46.1k
        rc = -1;
737
46.1k
      }
738
50.5k
        }
739
15.5k
      else if(!afx->not_dash_escaped)
740
13.5k
        {
741
    /* Bad dash-escaping. */
742
13.5k
    log_info (_("invalid dash escaped line: "));
743
13.5k
    es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
744
13.5k
    log_printf ("\n");
745
13.5k
        }
746
66.9k
    }
747
748
  /* Now handle the end-of-line canonicalization */
749
5.05M
  if( !afx->not_dash_escaped || this_truncated)
750
4.86M
    {
751
4.86M
      int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
752
753
4.86M
      afx->buffer_len=
754
4.86M
        trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
755
4.86M
           " \t\r\n");
756
4.86M
      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
4.86M
      if( crlf )
775
6.49k
        afx->buffer[afx->buffer_len++] = '\r';
776
4.86M
      afx->buffer[afx->buffer_len++] = this_truncated? '\f':'\n';
777
4.86M
      afx->buffer[afx->buffer_len] = '\0';
778
4.86M
    }
779
5.05M
    }
780
781
50.3k
    if( lastline ) { /* write last (ending) length header */
782
46.1k
        if(tempbuf_len<192)
783
41.2k
    buf[len++]=tempbuf_len;
784
4.87k
  else
785
4.87k
    {
786
4.87k
      buf[len++]=((tempbuf_len-192)/256) + 192;
787
4.87k
      buf[len++]=(tempbuf_len-192) % 256;
788
4.87k
    }
789
46.1k
  memcpy(&buf[len],tempbuf,tempbuf_len);
790
46.1k
  len+=tempbuf_len;
791
792
46.1k
  rc = 0;
793
46.1k
  afx->faked = 0;
794
46.1k
  afx->in_cleartext = 0;
795
  /* and now read the header lines */
796
46.1k
  afx->buffer_pos = 0;
797
48.2k
  for(;;) {
798
48.2k
      int i;
799
800
      /* read the next line (skip all truncated lines) */
801
48.3k
      do {
802
48.3k
    maxlen = MAX_LINELEN;
803
48.3k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
804
48.3k
             &afx->buffer_size, &maxlen );
805
48.3k
      } while( !maxlen );
806
48.2k
      p = afx->buffer;
807
48.2k
      n = afx->buffer_len;
808
48.2k
      if( !n ) {
809
790
    rc = -1;
810
790
    break; /* eof */
811
790
      }
812
47.4k
      i = parse_header_line( afx, p , n );
813
47.4k
      if( i <= 0 ) {
814
45.3k
    if( i )
815
31.6k
        invalid_armor();
816
45.3k
    break;
817
45.3k
      }
818
47.4k
  }
819
46.1k
  afx->inp_checked = 1;
820
46.1k
  gcry_md_reset (afx->crc_md);
821
46.1k
  afx->idx = 0;
822
46.1k
  afx->radbuf[0] = 0;
823
46.1k
    }
824
825
50.3k
    *retn = len;
826
50.3k
    return rc;
827
50.3k
}
828
829
830
static int
831
invalid_crc(void)
832
877
{
833
877
  if ( opt.ignore_crc_error )
834
0
    return 0;
835
877
  log_inc_errorcount();
836
877
  return gpg_error (GPG_ERR_INV_ARMOR);
837
877
}
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
77.9k
{
844
77.9k
    byte val;
845
77.9k
    int c;
846
77.9k
    u32 binc;
847
77.9k
    int checkcrc=0;
848
77.9k
    int rc = 0;
849
77.9k
    size_t n = 0;
850
77.9k
    int idx, onlypad=0;
851
77.9k
    int skip_fast = 0;
852
853
77.9k
    idx = afx->idx;
854
77.9k
    val = afx->radbuf[0];
855
4.83M
    for( n=0; n < size; ) {
856
857
4.83M
  if( afx->buffer_pos < afx->buffer_len )
858
4.68M
      c = afx->buffer[afx->buffer_pos++];
859
155k
  else { /* read the next line */
860
155k
      unsigned maxlen = MAX_LINELEN;
861
155k
      afx->buffer_pos = 0;
862
155k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
863
155k
                 &afx->buffer_size, &maxlen );
864
155k
      if( !maxlen )
865
104
    afx->truncated++;
866
155k
      if( !afx->buffer_len )
867
6.54k
    break; /* eof */
868
149k
      continue;
869
155k
  }
870
871
4.68M
      again:
872
4.68M
  binc = asctobin[0][c];
873
874
4.68M
  if( binc != 0xffffffffUL )
875
928k
    {
876
928k
      if( idx == 0 && skip_fast == 0
877
928k
    && afx->buffer_pos + (16 - 1) < afx->buffer_len
878
928k
    && n + 12 < size)
879
394k
        {
880
    /* Fast path for radix64 to binary conversion.  */
881
394k
    u32 b0,b1,b2,b3;
882
883
    /* Speculatively load 15 more input bytes.  */
884
394k
    b0 = binc << (3 * 6);
885
394k
    b0 |= asctobin[2][afx->buffer[afx->buffer_pos + 0]];
886
394k
    b0 |= asctobin[1][afx->buffer[afx->buffer_pos + 1]];
887
394k
    b0 |= asctobin[0][afx->buffer[afx->buffer_pos + 2]];
888
394k
    b1  = asctobin[3][afx->buffer[afx->buffer_pos + 3]];
889
394k
    b1 |= asctobin[2][afx->buffer[afx->buffer_pos + 4]];
890
394k
    b1 |= asctobin[1][afx->buffer[afx->buffer_pos + 5]];
891
394k
    b1 |= asctobin[0][afx->buffer[afx->buffer_pos + 6]];
892
394k
    b2  = asctobin[3][afx->buffer[afx->buffer_pos + 7]];
893
394k
    b2 |= asctobin[2][afx->buffer[afx->buffer_pos + 8]];
894
394k
    b2 |= asctobin[1][afx->buffer[afx->buffer_pos + 9]];
895
394k
    b2 |= asctobin[0][afx->buffer[afx->buffer_pos + 10]];
896
394k
    b3  = asctobin[3][afx->buffer[afx->buffer_pos + 11]];
897
394k
    b3 |= asctobin[2][afx->buffer[afx->buffer_pos + 12]];
898
394k
    b3 |= asctobin[1][afx->buffer[afx->buffer_pos + 13]];
899
394k
    b3 |= asctobin[0][afx->buffer[afx->buffer_pos + 14]];
900
901
    /* Check if any of the input bytes were invalid. */
902
394k
    if( (b0 | b1 | b2 | b3) != 0xffffffffUL )
903
303k
      {
904
        /* All 16 bytes are valid. */
905
303k
        buf[n + 0] = b0 >> (2 * 8);
906
303k
        buf[n + 1] = b0 >> (1 * 8);
907
303k
        buf[n + 2] = b0 >> (0 * 8);
908
303k
        buf[n + 3] = b1 >> (2 * 8);
909
303k
        buf[n + 4] = b1 >> (1 * 8);
910
303k
        buf[n + 5] = b1 >> (0 * 8);
911
303k
        buf[n + 6] = b2 >> (2 * 8);
912
303k
        buf[n + 7] = b2 >> (1 * 8);
913
303k
        buf[n + 8] = b2 >> (0 * 8);
914
303k
        buf[n + 9] = b3 >> (2 * 8);
915
303k
        buf[n + 10] = b3 >> (1 * 8);
916
303k
        buf[n + 11] = b3 >> (0 * 8);
917
303k
        afx->buffer_pos += 16 - 1;
918
303k
        n += 12;
919
303k
        continue;
920
303k
      }
921
90.3k
    else if( b0 == 0xffffffffUL )
922
47.3k
      {
923
        /* byte[1..3] have invalid character(s).  Switch to slow
924
           path.  */
925
47.3k
        skip_fast = 1;
926
47.3k
      }
927
42.9k
    else if( b1 == 0xffffffffUL )
928
23.5k
      {
929
        /* byte[4..7] have invalid character(s), first 4 bytes are
930
           valid.  */
931
23.5k
        buf[n + 0] = b0 >> (2 * 8);
932
23.5k
        buf[n + 1] = b0 >> (1 * 8);
933
23.5k
        buf[n + 2] = b0 >> (0 * 8);
934
23.5k
        afx->buffer_pos += 4 - 1;
935
23.5k
        n += 3;
936
23.5k
        skip_fast = 1;
937
23.5k
        continue;
938
23.5k
      }
939
19.3k
    else if( b2 == 0xffffffffUL )
940
11.0k
      {
941
        /* byte[8..11] have invalid character(s), first 8 bytes are
942
           valid.  */
943
11.0k
        buf[n + 0] = b0 >> (2 * 8);
944
11.0k
        buf[n + 1] = b0 >> (1 * 8);
945
11.0k
        buf[n + 2] = b0 >> (0 * 8);
946
11.0k
        buf[n + 3] = b1 >> (2 * 8);
947
11.0k
        buf[n + 4] = b1 >> (1 * 8);
948
11.0k
        buf[n + 5] = b1 >> (0 * 8);
949
11.0k
        afx->buffer_pos += 8 - 1;
950
11.0k
        n += 6;
951
11.0k
        skip_fast = 1;
952
11.0k
        continue;
953
11.0k
      }
954
8.28k
    else /*if( b3 == 0xffffffffUL )*/
955
8.28k
      {
956
        /* byte[12..15] have invalid character(s), first 12 bytes
957
           are valid.  */
958
8.28k
        buf[n + 0] = b0 >> (2 * 8);
959
8.28k
        buf[n + 1] = b0 >> (1 * 8);
960
8.28k
        buf[n + 2] = b0 >> (0 * 8);
961
8.28k
        buf[n + 3] = b1 >> (2 * 8);
962
8.28k
        buf[n + 4] = b1 >> (1 * 8);
963
8.28k
        buf[n + 5] = b1 >> (0 * 8);
964
8.28k
        buf[n + 6] = b2 >> (2 * 8);
965
8.28k
        buf[n + 7] = b2 >> (1 * 8);
966
8.28k
        buf[n + 8] = b2 >> (0 * 8);
967
8.28k
        afx->buffer_pos += 12 - 1;
968
8.28k
        n += 9;
969
8.28k
        skip_fast = 1;
970
8.28k
        continue;
971
8.28k
      }
972
394k
        }
973
974
581k
      switch(idx)
975
581k
        {
976
167k
    case 0: val =  binc << 2; break;
977
144k
    case 1: val |= (binc>>4)&3; buf[n++]=val;val=(binc<<4)&0xf0;break;
978
139k
    case 2: val |= (binc>>2)&15; buf[n++]=val;val=(binc<<6)&0xc0;break;
979
130k
    case 3: val |= binc&0x3f; buf[n++] = val; break;
980
581k
        }
981
581k
      idx = (idx+1) % 4;
982
983
581k
      continue;
984
581k
    }
985
986
3.75M
  skip_fast = 0;
987
988
3.75M
  if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
989
201k
      continue;
990
3.55M
  else if( c == '=' ) { /* pad character: stop */
991
      /* some mailers leave quoted-printable encoded characters
992
       * so we try to workaround this */
993
73.2k
      if( afx->buffer_pos+2 < afx->buffer_len ) {
994
27.1k
    int cc1, cc2, cc3;
995
27.1k
    cc1 = afx->buffer[afx->buffer_pos];
996
27.1k
    cc2 = afx->buffer[afx->buffer_pos+1];
997
27.1k
    cc3 = afx->buffer[afx->buffer_pos+2];
998
27.1k
    if( isxdigit(cc1) && isxdigit(cc2)
999
27.1k
          && strchr( "=\n\r\t ", cc3 )) {
1000
        /* well it seems to be the case - adjust */
1001
2.80k
        c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
1002
2.80k
        c <<= 4;
1003
2.80k
        c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
1004
2.80k
        afx->buffer_pos += 2;
1005
2.80k
        afx->qp_detected = 1;
1006
2.80k
        goto again;
1007
2.80k
    }
1008
27.1k
      }
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
70.4k
            if (afx->buffer_pos + 6 < afx->buffer_len
1016
70.4k
                && afx->buffer[afx->buffer_pos + 0] == '3'
1017
70.4k
                && afx->buffer[afx->buffer_pos + 1] == 'D'
1018
70.4k
                && asctobin[0][afx->buffer[afx->buffer_pos + 2]] != 0xffffffffUL
1019
70.4k
                && asctobin[0][afx->buffer[afx->buffer_pos + 3]] != 0xffffffffUL
1020
70.4k
                && asctobin[0][afx->buffer[afx->buffer_pos + 4]] != 0xffffffffUL
1021
70.4k
                && asctobin[0][afx->buffer[afx->buffer_pos + 5]] != 0xffffffffUL
1022
70.4k
                && afx->buffer[afx->buffer_pos + 6] == '\n')
1023
3
              {
1024
3
                afx->buffer_pos += 2;
1025
3
                afx->qp_detected = 1;
1026
3
              }
1027
1028
70.4k
      if (!n)
1029
49.8k
        onlypad = 1;
1030
1031
70.4k
      if( idx == 1 )
1032
22.3k
    buf[n++] = val;
1033
70.4k
      checkcrc++;
1034
70.4k
      break;
1035
73.2k
  }
1036
3.48M
        else if (afx->dearmor_state && c == '-'
1037
3.48M
                 && afx->buffer_pos + 8 < afx->buffer_len
1038
3.48M
                 && !strncmp (afx->buffer, "-----END ", 8)) {
1039
0
            break; /* End in --dearmor mode.  */
1040
0
        }
1041
3.48M
  else {
1042
3.48M
      log_error(_("invalid radix64 character %02X skipped\n"), c);
1043
3.48M
      continue;
1044
3.48M
  }
1045
3.75M
    }
1046
1047
77.9k
    afx->idx = idx;
1048
77.9k
    afx->radbuf[0] = val;
1049
1050
77.9k
    if( n )
1051
41.3k
      gcry_md_write (afx->crc_md, buf, n);
1052
1053
77.9k
    if( checkcrc ) {
1054
70.4k
  gcry_md_final (afx->crc_md);
1055
70.4k
  afx->any_data = 1;
1056
70.4k
  afx->inp_checked=0;
1057
70.4k
  afx->faked = 0;
1058
106k
  for(;;) { /* skip lf and pad characters */
1059
106k
      if( afx->buffer_pos < afx->buffer_len )
1060
96.0k
    c = afx->buffer[afx->buffer_pos++];
1061
10.2k
      else { /* read the next line */
1062
10.2k
    unsigned maxlen = MAX_LINELEN;
1063
10.2k
    afx->buffer_pos = 0;
1064
10.2k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1065
10.2k
               &afx->buffer_size, &maxlen );
1066
10.2k
    if( !maxlen )
1067
69
        afx->truncated++;
1068
10.2k
    if( !afx->buffer_len )
1069
275
        break; /* eof */
1070
9.95k
    continue;
1071
10.2k
      }
1072
96.0k
      if( c == '\n' || c == ' ' || c == '\r'
1073
96.0k
    || c == '\t' || c == '=' )
1074
25.9k
    continue;
1075
70.1k
      break;
1076
96.0k
  }
1077
70.4k
  if( !afx->buffer_len )
1078
275
      log_error(_("premature eof (no CRC)\n"));
1079
70.1k
  else {
1080
70.1k
      u32 mycrc = 0;
1081
70.1k
      idx = 0;
1082
77.8k
      do {
1083
77.8k
    if( (binc = asctobin[0][c]) == 0xffffffffUL )
1084
67.5k
        break;
1085
10.3k
    switch(idx) {
1086
2.89k
      case 0: val =  binc << 2; break;
1087
2.61k
      case 1: val |= (binc>>4)&3; mycrc |= val << 16;val=(binc<<4)&0xf0;break;
1088
2.45k
      case 2: val |= (binc>>2)&15; mycrc |= val << 8;val=(binc<<6)&0xc0;break;
1089
2.38k
      case 3: val |= binc&0x3f; mycrc |= val; break;
1090
10.3k
    }
1091
10.3k
    for(;;) {
1092
10.3k
        if( afx->buffer_pos < afx->buffer_len )
1093
10.0k
      c = afx->buffer[afx->buffer_pos++];
1094
278
        else { /* read the next line */
1095
278
      unsigned maxlen = MAX_LINELEN;
1096
278
      afx->buffer_pos = 0;
1097
278
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1098
278
                 &afx->buffer_size,
1099
278
                &maxlen );
1100
278
      if( !maxlen )
1101
0
          afx->truncated++;
1102
278
      if( !afx->buffer_len )
1103
278
          break; /* eof */
1104
0
      continue;
1105
278
        }
1106
10.0k
        break;
1107
10.3k
    }
1108
10.3k
    if( !afx->buffer_len )
1109
278
        break; /* eof */
1110
10.3k
      } while( ++idx < 4 );
1111
70.1k
      if( !afx->buffer_len ) {
1112
278
    log_info(_("premature eof (in CRC)\n"));
1113
278
    rc = invalid_crc();
1114
278
      }
1115
69.9k
      else if( idx == 0 ) {
1116
          /* No CRC at all is legal ("MAY") */
1117
67.2k
          rc=0;
1118
67.2k
      }
1119
2.62k
      else if( idx != 4 ) {
1120
257
    log_info(_("malformed CRC\n"));
1121
257
    rc = invalid_crc();
1122
257
      }
1123
2.36k
      else if( mycrc != get_afx_crc (afx) ) {
1124
342
    log_info (_("CRC error; %06lX - %06lX\n"),
1125
342
            (ulong)get_afx_crc (afx), (ulong)mycrc);
1126
342
    rc = invalid_crc();
1127
342
      }
1128
2.02k
      else {
1129
2.02k
    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
2.02k
      }
1153
70.1k
  }
1154
70.4k
    }
1155
1156
77.9k
    if( !n && !onlypad )
1157
4.74k
  rc = -1;
1158
1159
77.9k
    *retn = n;
1160
77.9k
    return rc;
1161
77.9k
}
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
209k
{
1285
209k
    size_t size = *ret_len;
1286
209k
    armor_filter_context_t *afx = opaque;
1287
209k
    int rc=0, c;
1288
209k
    byte radbuf[3];
1289
209k
    int  idx, idx2;
1290
209k
    size_t n=0;
1291
209k
    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
209k
    if( DBG_FILTER )
1302
0
  log_debug("armor-filter: control: %d\n", control );
1303
209k
    if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
1304
4.90k
  n = 0;
1305
4.90k
  if( afx->buffer_len ) {
1306
            /* Copy the data from AFX->BUFFER to BUF.  */
1307
5.30M
      for(; n < size && afx->buffer_pos < afx->buffer_len; n++ )
1308
5.30M
    buf[n++] = afx->buffer[afx->buffer_pos++];
1309
1.44k
      if( afx->buffer_pos >= afx->buffer_len )
1310
594
    afx->buffer_len = 0;
1311
1.44k
  }
1312
        /* If there is still space in BUF, read directly into it.  */
1313
21.3M
  for(; n < size; n++ ) {
1314
21.3M
      if( (c=iobuf_get(a)) == -1 )
1315
2.05k
    break;
1316
21.3M
      buf[n] = c & 0xff;
1317
21.3M
  }
1318
4.90k
  if( !n )
1319
            /* We didn't get any data.  EOF.  */
1320
1.12k
      rc = -1;
1321
4.90k
  *ret_len = n;
1322
4.90k
    }
1323
204k
    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
179k
  if( size < PARTIAL_CHUNK+1 )
1328
0
      BUG(); /* supplied buffer too short */
1329
1330
179k
  if( afx->faked )
1331
50.3k
      rc = fake_packet( afx, a, &n, buf, size );
1332
128k
  else if( !afx->inp_checked ) {
1333
81.4k
      rc = check_input( afx, a );
1334
81.4k
      if( afx->inp_bypass ) {
1335
2.20M
    for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
1336
2.20M
        buf[n++] = afx->buffer[afx->buffer_pos++];
1337
1.55k
    if( afx->buffer_pos >= afx->buffer_len )
1338
920
        afx->buffer_len = 0;
1339
1.55k
    if( !n )
1340
210
        rc = -1;
1341
1.55k
      }
1342
79.8k
      else if( afx->faked ) {
1343
48.9k
          unsigned int hashes = afx->hashes;
1344
48.9k
                const byte *sesmark;
1345
48.9k
                size_t sesmarklen;
1346
1347
48.9k
                sesmark = get_session_marker( &sesmarklen );
1348
48.9k
                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
48.9k
    hashes &= 1|2|8|16|32|64;
1355
48.9k
    if( !hashes ) {
1356
35.3k
        hashes |= 2;  /* Default to SHA-1. */
1357
35.3k
    }
1358
48.9k
    n=0;
1359
                /* First a gpg control packet... */
1360
48.9k
                buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1361
48.9k
                n++;   /* see below */
1362
48.9k
                memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1363
48.9k
                buf[n++] = CTRLPKT_CLEARSIGN_START;
1364
48.9k
                buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1365
48.9k
                if( hashes & 1 )
1366
3.02k
                    buf[n++] = DIGEST_ALGO_RMD160;
1367
48.9k
                if( hashes & 2 )
1368
37.6k
                    buf[n++] = DIGEST_ALGO_SHA1;
1369
48.9k
                if( hashes & 8 )
1370
1.29k
                    buf[n++] = DIGEST_ALGO_SHA224;
1371
48.9k
                if( hashes & 16 )
1372
7.22k
                    buf[n++] = DIGEST_ALGO_SHA256;
1373
48.9k
                if( hashes & 32 )
1374
1.63k
                    buf[n++] = DIGEST_ALGO_SHA384;
1375
48.9k
                if( hashes & 64 )
1376
905
                    buf[n++] = DIGEST_ALGO_SHA512;
1377
48.9k
                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
48.9k
    buf[n++] = 0xCB; /* new packet format, type 11 */
1385
48.9k
    buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1386
48.9k
    buf[n++] = 't';  /* canonical text mode */
1387
48.9k
    buf[n++] = 0;  /* namelength */
1388
48.9k
    buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1389
48.9k
    memset(buf+n, 0, 4); /* timestamp */
1390
48.9k
    n += 4;
1391
48.9k
      }
1392
30.8k
      else if( !rc )
1393
30.6k
    rc = radix64_read( afx, a, &n, buf, size );
1394
81.4k
  }
1395
47.3k
  else
1396
47.3k
      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
179k
  *ret_len = n;
1403
179k
    }
1404
25.6k
    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
25.6k
    else if( control == IOBUFCTRL_INIT )
1478
12.8k
      {
1479
12.8k
  if( !is_initialized )
1480
4
    initialize();
1481
1482
  /* Figure out what we're using for line endings if the caller
1483
     didn't specify. */
1484
12.8k
  if(afx->eol[0]==0)
1485
12.8k
    {
1486
#ifdef HAVE_DOSISH_SYSTEM
1487
      afx->eol[0]='\r';
1488
      afx->eol[1]='\n';
1489
#else
1490
12.8k
      afx->eol[0]='\n';
1491
12.8k
#endif
1492
12.8k
    }
1493
12.8k
      }
1494
12.8k
    else if( control == IOBUFCTRL_CANCEL ) {
1495
0
  afx->cancel = 1;
1496
0
    }
1497
12.8k
    else if( control == IOBUFCTRL_FREE ) {
1498
12.8k
  if( afx->cancel )
1499
0
      ;
1500
12.8k
  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
12.8k
  else if( !afx->any_data && !afx->inp_bypass ) {
1554
6.74k
      log_error(_("no valid OpenPGP data found.\n"));
1555
6.74k
      afx->no_openpgp_data = 1;
1556
6.74k
      write_status_text( STATUS_NODATA, "1" );
1557
6.74k
  }
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
12.8k
  if( afx->truncated )
1564
92
      log_info(_("invalid armor: line longer than %d characters\n"),
1565
92
          MAX_LINELEN );
1566
  /* issue an error to enforce dissemination of correct software */
1567
12.8k
  if( afx->qp_detected )
1568
183
      log_error(_("quoted printable character in armor - "
1569
183
      "probably a buggy MTA has been used\n") );
1570
12.8k
  xfree( afx->buffer );
1571
12.8k
  afx->buffer = NULL;
1572
12.8k
        release_armor_context (afx);
1573
12.8k
    }
1574
0
    else if( control == IOBUFCTRL_DESC )
1575
0
        mem2str (buf, "armor_filter", *ret_len);
1576
209k
    return rc;
1577
209k
}
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
}