Coverage Report

Created: 2026-08-31 07:21

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