Coverage Report

Created: 2026-02-09 07:03

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
3.80M
#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.50k
#define BEGIN_SIGNATURE 2
83
19.5k
#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.27k
{
116
3.27k
  armor_filter_context_t *afx;
117
3.27k
  gpg_error_t err;
118
119
3.27k
  afx = xcalloc (1, sizeof *afx);
120
3.27k
  if (afx)
121
3.27k
    {
122
3.27k
      err = gcry_md_open (&afx->crc_md, GCRY_MD_CRC24_RFC2440, 0);
123
3.27k
      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.27k
      afx->refcount = 1;
132
3.27k
    }
133
134
3.27k
  return afx;
135
3.27k
}
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
15.7k
{
142
15.7k
  if (!afx)
143
9.16k
    return;
144
15.7k
  log_assert (afx->refcount);
145
6.54k
  if ( --afx->refcount )
146
3.27k
    return;
147
3.27k
  gcry_md_close (afx->crc_md);
148
3.27k
  xfree (afx);
149
3.27k
}
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.27k
{
155
3.27k
  int rc;
156
157
3.27k
  afx->refcount++;
158
3.27k
  rc = iobuf_push_filter (iobuf, armor_filter, afx);
159
3.27k
  if (rc)
160
0
    afx->refcount--;
161
3.27k
  return rc;
162
3.27k
}
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.01k
{
200
1.01k
  const byte *crc_buf;
201
1.01k
  u32 crc;
202
203
1.01k
  crc_buf = gcry_md_read (afx->crc_md, GCRY_MD_CRC24_RFC2440);
204
205
1.01k
  crc = crc_buf[0];
206
1.01k
  crc <<= 8;
207
1.01k
  crc |= crc_buf[1];
208
1.01k
  crc <<= 8;
209
1.01k
  crc |= crc_buf[2];
210
211
1.01k
  return crc;
212
1.01k
}
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
31.4k
{
227
31.4k
  int ctb, pkttype;
228
31.4k
  int indeterminate_length_allowed;
229
230
31.4k
    ctb = *buf;
231
31.4k
    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
17.1k
      return 1;
236
237
14.2k
    pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
238
14.2k
    switch( pkttype ) {
239
174
      case PKT_PUBKEY_ENC:
240
2.95k
      case PKT_SIGNATURE:
241
3.12k
      case PKT_SYMKEY_ENC:
242
4.43k
      case PKT_ONEPASS_SIG:
243
4.54k
      case PKT_SECRET_KEY:
244
4.63k
      case PKT_PUBLIC_KEY:
245
5.08k
      case PKT_SECRET_SUBKEY:
246
5.19k
      case PKT_MARKER:
247
5.60k
      case PKT_RING_TRUST:
248
5.81k
      case PKT_USER_ID:
249
5.93k
      case PKT_PUBLIC_SUBKEY:
250
6.14k
      case PKT_ATTRIBUTE:
251
6.79k
      case PKT_MDC:
252
6.79k
  indeterminate_length_allowed = 0;
253
6.79k
        break;
254
255
2.07k
      case PKT_COMPRESSED:
256
2.24k
      case PKT_ENCRYPTED:
257
2.31k
      case PKT_ENCRYPTED_MDC:
258
2.43k
      case PKT_ENCRYPTED_AEAD:
259
3.44k
      case PKT_PLAINTEXT:
260
3.49k
      case PKT_OLD_COMMENT:
261
3.66k
      case PKT_COMMENT:
262
3.77k
      case PKT_GPG_CONTROL:
263
3.77k
  indeterminate_length_allowed = 1;
264
3.77k
        break;
265
266
3.69k
      default:
267
        /* Invalid packet type.  */
268
3.69k
        return 1;
269
14.2k
    }
270
271
10.5k
    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
6.79k
      {
277
6.79k
        int new_format;
278
6.79k
        int indeterminate_length;
279
280
6.79k
        new_format = !! (ctb & (1 << 6));
281
6.79k
        if (new_format)
282
2.51k
          indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
283
4.27k
        else
284
4.27k
          indeterminate_length = (ctb & 3) == 3;
285
286
6.79k
        if (indeterminate_length)
287
1.16k
          return 1;
288
6.79k
      }
289
290
    /* The first CTB seems legit.  It is probably not armored
291
       data.  */
292
9.41k
    return 0;
293
10.5k
}
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
12.4k
{
304
12.4k
    byte buf[2];
305
12.4k
    int n;
306
307
    /* fixme: there might be a problem with iobuf_peek */
308
12.4k
    n = iobuf_peek (a, buf, 2);
309
12.4k
    if( n == -1 )
310
0
  return 0; /* EOF, doesn't matter whether armored or not */
311
12.4k
    if( !n )
312
0
  return 1; /* can't check it: try armored */
313
12.4k
    if (n != 2)
314
30
  return 0; /* short buffer */
315
12.4k
    return is_armored(buf);
316
12.4k
}
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
4.43k
{
339
4.43k
    const char *s, *s2;
340
4.43k
    unsigned found = 0;
341
342
4.43k
    if( strlen(line) < 6  || strlen(line) > 60 )
343
108
  return 0; /* too short or too long */
344
4.32k
    if( memcmp( line, "Hash:", 5 ) )
345
1.11k
  return 0; /* invalid header */
346
347
11.6k
    for(s=line+5;;s=s2) {
348
14.8k
  for(; *s && (*s==' ' || *s == '\t'); s++ )
349
3.23k
      ;
350
11.6k
  if( !*s )
351
1.58k
      break;
352
29.8k
  for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
353
19.7k
      ;
354
10.0k
  if( !strncmp( s, "RIPEMD160", s2-s ) )
355
883
      found |= 1;
356
9.19k
  else if( !strncmp( s, "SHA1", s2-s ) )
357
7.52k
      found |= 2;
358
1.67k
  else if( !strncmp( s, "SHA224", s2-s ) )
359
26
      found |= 8;
360
1.64k
  else if( !strncmp( s, "SHA256", s2-s ) )
361
226
      found |= 16;
362
1.42k
  else if( !strncmp( s, "SHA384", s2-s ) )
363
115
      found |= 32;
364
1.30k
  else if( !strncmp( s, "SHA512", s2-s ) )
365
233
      found |= 64;
366
1.07k
  else
367
1.07k
      return 0;
368
14.0k
  for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
369
5.02k
      ;
370
9.00k
  if( *s2 && *s2 != ',' )
371
554
      return 0;
372
8.45k
  if( *s2 )
373
6.87k
      s2++;
374
8.45k
    }
375
1.58k
    return found;
376
3.21k
}
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.03k
{
382
5.03k
  if(strncmp(line,"Version",7)==0
383
4.32k
     || strncmp(line,"Comment",7)==0
384
4.05k
     || strncmp(line,"MessageID",9)==0
385
3.75k
     || strncmp(line,"Hash",4)==0
386
3.22k
     || strncmp(line,"Charset",7)==0)
387
2.27k
    return 1;
388
389
2.75k
  return 0;
390
5.03k
}
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
2.01M
{
400
2.01M
    const char *s;
401
2.01M
    byte *save_p, *p;
402
2.01M
    int save_c;
403
2.01M
    int i;
404
405
2.01M
    if( len < 15 )
406
1.86M
  return -1; /* too short */
407
153k
    if( memcmp( line, "-----", 5 ) )
408
119k
  return -1; /* no */
409
34.0k
    p = strstr( line+5, "-----");
410
34.0k
    if( !p )
411
5.20k
  return -1;
412
28.8k
    save_p = p;
413
28.8k
    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
28.8k
    if(RFC2440)
424
0
      {
425
0
  if( *p == '\r' )
426
0
    p++;
427
0
  if( *p == '\n' )
428
0
    p++;
429
0
      }
430
28.8k
    else
431
54.1k
      while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
432
25.2k
  p++;
433
434
28.8k
    if( *p )
435
5.08k
  return -1; /* garbage after dashes */
436
23.7k
    save_c = *save_p; *save_p = 0;
437
23.7k
    p = line+5;
438
83.0k
    for(i=0; (s=head_strings[i]); i++ )
439
79.1k
  if( !strcmp(s, p) )
440
19.9k
      break;
441
23.7k
    *save_p = save_c;
442
23.7k
    if (!s)
443
3.84k
      {
444
3.84k
        if (!strncmp (p, "BEGIN ", 6))
445
2.05k
          return 42;
446
1.79k
  return -1; /* unknown armor line */
447
3.84k
      }
448
449
19.9k
    if( opt.verbose > 1 )
450
19.9k
  log_info(_("armor: %s\n"), head_strings[i]);
451
19.9k
    return i;
452
23.7k
}
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
32.3k
{
465
32.3k
    byte *p;
466
32.3k
    int hashes=0;
467
32.3k
    unsigned int len2;
468
469
32.3k
    len2 = length_sans_trailing_ws ( line, len );
470
32.3k
    if( !len2 ) {
471
12.1k
        afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
472
12.1k
  return 0; /* WS only: same as empty line */
473
12.1k
    }
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
20.2k
    p = strchr( line, ':');
486
20.2k
    if (!p && afx->dearmor_state)
487
0
      return 0; /* Special treatment in --dearmor mode.  */
488
20.2k
    if( !p || (RFC2440 && p[1]!=' ')
489
9.99k
  || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
490
10.7k
      {
491
10.7k
  log_error (_("invalid armor header: "));
492
10.7k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
493
10.7k
  log_printf ("\n");
494
10.7k
  return -1;
495
10.7k
      }
496
497
    /* Chop off the whitespace we detected before */
498
9.46k
    len=len2;
499
9.46k
    line[len2]='\0';
500
501
9.46k
    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
9.46k
    if (afx->dearmor_mode)
508
0
      ;
509
9.46k
    else if (afx->in_cleartext)
510
4.43k
      {
511
4.43k
  if( (hashes=parse_hash_header( line )) )
512
1.58k
    afx->hashes |= hashes;
513
2.84k
  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
2.84k
  else
518
2.84k
    {
519
2.84k
      log_error(_("invalid clearsig header\n"));
520
2.84k
      return -1;
521
2.84k
    }
522
4.43k
      }
523
5.03k
    else if(!is_armor_tag(line))
524
2.75k
      {
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
2.75k
  log_info(_("unknown armor header: "));
533
2.75k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
534
2.75k
  log_printf ("\n");
535
2.75k
      }
536
537
6.61k
    return 1;
538
9.46k
}
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
20.5k
{
546
20.5k
    int rc = 0;
547
20.5k
    int i;
548
20.5k
    byte *line;
549
20.5k
    unsigned len;
550
20.5k
    unsigned maxlen;
551
20.5k
    int hdr_line = -1;
552
553
    /* read the first line to see whether this is armored data */
554
20.5k
    maxlen = MAX_LINELEN;
555
20.5k
    len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
556
20.5k
               &afx->buffer_size, &maxlen );
557
20.5k
    line = afx->buffer;
558
20.5k
    if( !maxlen ) {
559
  /* line has been truncated: assume not armored */
560
12
  afx->inp_checked = 1;
561
12
  afx->inp_bypass = 1;
562
12
  return 0;
563
12
    }
564
565
20.5k
    if( !len ) {
566
54
  return -1; /* eof */
567
54
    }
568
569
    /* (the line is always a C string but maybe longer) */
570
20.4k
    if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
571
1.45k
  ;
572
19.0k
    else if (len >= 2 && !is_armored (line)) {
573
280
  afx->inp_checked = 1;
574
280
  afx->inp_bypass = 1;
575
280
  return 0;
576
280
    }
577
578
    /* find the armor header */
579
2.00M
    while(len) {
580
2.00M
  i = is_armor_header( line, len );
581
2.00M
        if ( i == 42 ) {
582
1.32k
            if (afx->dearmor_mode) {
583
0
                afx->dearmor_state = 1;
584
0
                break;
585
0
            }
586
1.32k
        }
587
2.00M
        else if (i >= 0
588
19.5k
                 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
589
19.5k
      hdr_line = i;
590
19.5k
      if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
591
7.10k
          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
7.10k
    afx->in_cleartext = 1;
596
7.10k
      }
597
19.5k
      break;
598
19.5k
  }
599
600
  /* read the next line (skip all truncated lines) */
601
1.98M
  do {
602
1.98M
      maxlen = MAX_LINELEN;
603
1.98M
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
604
1.98M
                 &afx->buffer_size, &maxlen );
605
1.98M
      line = afx->buffer;
606
1.98M
      len = afx->buffer_len;
607
1.98M
  } while( !maxlen );
608
1.98M
    }
609
610
    /* Parse the header lines.  */
611
25.2k
    while(len) {
612
  /* Read the next line (skip all truncated lines). */
613
24.6k
  do {
614
24.6k
      maxlen = MAX_LINELEN;
615
24.6k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
616
24.6k
                 &afx->buffer_size, &maxlen );
617
24.6k
      line = afx->buffer;
618
24.6k
      len = afx->buffer_len;
619
24.6k
  } while( !maxlen );
620
621
24.6k
  i = parse_header_line( afx, line, len );
622
24.6k
  if( i <= 0 ) {
623
19.5k
      if (i && RFC2440)
624
0
    rc = GPG_ERR_INV_ARMOR;
625
19.5k
      break;
626
19.5k
  }
627
24.6k
    }
628
629
630
20.1k
    if( rc )
631
0
  invalid_armor();
632
20.1k
    else if( afx->in_cleartext )
633
7.10k
  afx->faked = 1;
634
13.0k
    else {
635
13.0k
  afx->inp_checked = 1;
636
13.0k
  gcry_md_reset (afx->crc_md);
637
13.0k
  afx->idx = 0;
638
13.0k
  afx->radbuf[0] = 0;
639
13.0k
    }
640
641
20.1k
    return rc;
642
20.4k
}
643
644
19.8M
#define PARTIAL_CHUNK 512
645
11.1k
#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
7.29k
{
656
7.29k
    int rc = 0;
657
7.29k
    size_t len = 0;
658
7.29k
    int lastline = 0;
659
7.29k
    unsigned maxlen, n;
660
7.29k
    byte *p;
661
7.29k
    byte tempbuf[PARTIAL_CHUNK];
662
7.29k
    size_t tempbuf_len=0;
663
7.29k
    int this_truncated;
664
665
1.51M
    while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
666
  /* copy what we have in the line buffer */
667
1.50M
  if( afx->faked == 1 )
668
7.06k
      afx->faked++; /* skip the first (empty) line */
669
1.50M
  else
670
1.50M
    {
671
      /* It's full, so write this partial chunk */
672
1.50M
      if(tempbuf_len==PARTIAL_CHUNK)
673
11.1k
        {
674
11.1k
    buf[len++]=0xE0+PARTIAL_POW;
675
11.1k
    memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
676
11.1k
    len+=PARTIAL_CHUNK;
677
11.1k
    tempbuf_len=0;
678
11.1k
    continue;
679
11.1k
        }
680
681
7.66M
      while( tempbuf_len < PARTIAL_CHUNK
682
7.65M
       && afx->buffer_pos < afx->buffer_len )
683
6.17M
        tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
684
1.48M
      if( tempbuf_len==PARTIAL_CHUNK )
685
11.1k
        continue;
686
1.48M
    }
687
688
  /* read the next line */
689
1.48M
  maxlen = MAX_LINELEN;
690
1.48M
  afx->buffer_pos = 0;
691
1.48M
  afx->buffer_len = iobuf_read_line( a, &afx->buffer,
692
1.48M
             &afx->buffer_size, &maxlen );
693
1.48M
  if( !afx->buffer_len ) {
694
558
      rc = -1; /* eof (should not happen) */
695
558
      continue;
696
558
  }
697
1.48M
  if( !maxlen )
698
25
          {
699
25
      afx->truncated++;
700
25
            this_truncated = 1;
701
25
          }
702
1.48M
        else
703
1.48M
          this_truncated = 0;
704
705
706
1.48M
  p = afx->buffer;
707
1.48M
  n = afx->buffer_len;
708
709
  /* Armor header or dash-escaped line? */
710
1.48M
  if(p[0]=='-')
711
12.3k
    {
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.3k
      if(p[1]==' ' && !afx->not_dash_escaped)
719
31
        {
720
    /* It's a dash-escaped line, so skip over the
721
       escape. */
722
31
    afx->buffer_pos = 2;
723
31
        }
724
12.2k
      else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
725
6.50k
        {
726
    /* Five dashes in a row mean it's probably armor
727
       header. */
728
6.50k
    int type = is_armor_header( p, n );
729
6.50k
                if (type == 42)
730
732
                  type = -1;  /* Only OpenPGP armors are expected.  */
731
6.50k
    if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
732
0
      ; /* this is okay */
733
6.50k
    else
734
6.50k
      {
735
6.50k
        if( type != BEGIN_SIGNATURE )
736
6.48k
          {
737
6.48k
      log_info(_("unexpected armor: "));
738
6.48k
      es_write_sanitized (log_get_stream (), p, n,
739
6.48k
                                            NULL, NULL);
740
6.48k
      log_printf ("\n");
741
6.48k
          }
742
743
6.50k
        lastline = 1;
744
6.50k
        rc = -1;
745
6.50k
      }
746
6.50k
        }
747
5.78k
      else if(!afx->not_dash_escaped)
748
5.78k
        {
749
    /* Bad dash-escaping. */
750
5.78k
    log_info (_("invalid dash escaped line: "));
751
5.78k
    es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
752
5.78k
    log_printf ("\n");
753
5.78k
        }
754
12.3k
    }
755
756
  /* Now handle the end-of-line canonicalization */
757
1.48M
  if( !afx->not_dash_escaped || this_truncated)
758
1.48M
    {
759
1.48M
      int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
760
761
1.48M
      afx->buffer_len=
762
1.48M
        trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
763
1.48M
           " \t\r\n");
764
1.48M
      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
1.48M
      if( crlf )
783
5.45k
        afx->buffer[afx->buffer_len++] = '\r';
784
1.48M
      afx->buffer[afx->buffer_len++] = this_truncated? '\f':'\n';
785
1.48M
      afx->buffer[afx->buffer_len] = '\0';
786
1.48M
    }
787
1.48M
    }
788
789
7.29k
    if( lastline ) { /* write last (ending) length header */
790
6.50k
        if(tempbuf_len<192)
791
5.25k
    buf[len++]=tempbuf_len;
792
1.25k
  else
793
1.25k
    {
794
1.25k
      buf[len++]=((tempbuf_len-192)/256) + 192;
795
1.25k
      buf[len++]=(tempbuf_len-192) % 256;
796
1.25k
    }
797
6.50k
  memcpy(&buf[len],tempbuf,tempbuf_len);
798
6.50k
  len+=tempbuf_len;
799
800
6.50k
  rc = 0;
801
6.50k
  afx->faked = 0;
802
6.50k
  afx->in_cleartext = 0;
803
  /* and now read the header lines */
804
6.50k
  afx->buffer_pos = 0;
805
8.05k
  for(;;) {
806
8.05k
      int i;
807
808
      /* read the next line (skip all truncated lines) */
809
8.05k
      do {
810
8.05k
    maxlen = MAX_LINELEN;
811
8.05k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
812
8.05k
             &afx->buffer_size, &maxlen );
813
8.05k
      } while( !maxlen );
814
8.05k
      p = afx->buffer;
815
8.05k
      n = afx->buffer_len;
816
8.05k
      if( !n ) {
817
296
    rc = -1;
818
296
    break; /* eof */
819
296
      }
820
7.75k
      i = parse_header_line( afx, p , n );
821
7.75k
      if( i <= 0 ) {
822
6.21k
    if( i )
823
0
        invalid_armor();
824
6.21k
    break;
825
6.21k
      }
826
7.75k
  }
827
6.50k
  afx->inp_checked = 1;
828
6.50k
  gcry_md_reset (afx->crc_md);
829
6.50k
  afx->idx = 0;
830
6.50k
  afx->radbuf[0] = 0;
831
6.50k
    }
832
833
7.29k
    *retn = len;
834
7.29k
    return rc;
835
7.29k
}
836
837
838
static int
839
invalid_crc(void)
840
276
{
841
276
  if ( opt.ignore_crc_error )
842
0
    return 0;
843
276
  log_inc_errorcount();
844
276
  return gpg_error (GPG_ERR_INV_ARMOR);
845
276
}
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
20.0k
{
852
20.0k
    byte val;
853
20.0k
    int c;
854
20.0k
    u32 binc;
855
20.0k
    int checkcrc=0;
856
20.0k
    int rc = 0;
857
20.0k
    size_t n = 0;
858
20.0k
    int idx, onlypad=0;
859
20.0k
    int skip_fast = 0;
860
861
20.0k
    idx = afx->idx;
862
20.0k
    val = afx->radbuf[0];
863
2.32M
    for( n=0; n < size; ) {
864
865
2.32M
  if( afx->buffer_pos < afx->buffer_len )
866
2.05M
      c = afx->buffer[afx->buffer_pos++];
867
270k
  else { /* read the next line */
868
270k
      unsigned maxlen = MAX_LINELEN;
869
270k
      afx->buffer_pos = 0;
870
270k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
871
270k
                 &afx->buffer_size, &maxlen );
872
270k
      if( !maxlen )
873
15
    afx->truncated++;
874
270k
      if( !afx->buffer_len )
875
1.61k
    break; /* eof */
876
268k
      continue;
877
270k
  }
878
879
2.05M
      again:
880
2.05M
  binc = asctobin[0][c];
881
882
2.05M
  if( binc != 0xffffffffUL )
883
814k
    {
884
814k
      if( idx == 0 && skip_fast == 0
885
268k
    && afx->buffer_pos + (16 - 1) < afx->buffer_len
886
160k
    && n + 12 < size)
887
159k
        {
888
    /* Fast path for radix64 to binary conversion.  */
889
159k
    u32 b0,b1,b2,b3;
890
891
    /* Speculatively load 15 more input bytes.  */
892
159k
    b0 = binc << (3 * 6);
893
159k
    b0 |= asctobin[2][afx->buffer[afx->buffer_pos + 0]];
894
159k
    b0 |= asctobin[1][afx->buffer[afx->buffer_pos + 1]];
895
159k
    b0 |= asctobin[0][afx->buffer[afx->buffer_pos + 2]];
896
159k
    b1  = asctobin[3][afx->buffer[afx->buffer_pos + 3]];
897
159k
    b1 |= asctobin[2][afx->buffer[afx->buffer_pos + 4]];
898
159k
    b1 |= asctobin[1][afx->buffer[afx->buffer_pos + 5]];
899
159k
    b1 |= asctobin[0][afx->buffer[afx->buffer_pos + 6]];
900
159k
    b2  = asctobin[3][afx->buffer[afx->buffer_pos + 7]];
901
159k
    b2 |= asctobin[2][afx->buffer[afx->buffer_pos + 8]];
902
159k
    b2 |= asctobin[1][afx->buffer[afx->buffer_pos + 9]];
903
159k
    b2 |= asctobin[0][afx->buffer[afx->buffer_pos + 10]];
904
159k
    b3  = asctobin[3][afx->buffer[afx->buffer_pos + 11]];
905
159k
    b3 |= asctobin[2][afx->buffer[afx->buffer_pos + 12]];
906
159k
    b3 |= asctobin[1][afx->buffer[afx->buffer_pos + 13]];
907
159k
    b3 |= asctobin[0][afx->buffer[afx->buffer_pos + 14]];
908
909
    /* Check if any of the input bytes were invalid. */
910
159k
    if( (b0 | b1 | b2 | b3) != 0xffffffffUL )
911
72.7k
      {
912
        /* All 16 bytes are valid. */
913
72.7k
        buf[n + 0] = b0 >> (2 * 8);
914
72.7k
        buf[n + 1] = b0 >> (1 * 8);
915
72.7k
        buf[n + 2] = b0 >> (0 * 8);
916
72.7k
        buf[n + 3] = b1 >> (2 * 8);
917
72.7k
        buf[n + 4] = b1 >> (1 * 8);
918
72.7k
        buf[n + 5] = b1 >> (0 * 8);
919
72.7k
        buf[n + 6] = b2 >> (2 * 8);
920
72.7k
        buf[n + 7] = b2 >> (1 * 8);
921
72.7k
        buf[n + 8] = b2 >> (0 * 8);
922
72.7k
        buf[n + 9] = b3 >> (2 * 8);
923
72.7k
        buf[n + 10] = b3 >> (1 * 8);
924
72.7k
        buf[n + 11] = b3 >> (0 * 8);
925
72.7k
        afx->buffer_pos += 16 - 1;
926
72.7k
        n += 12;
927
72.7k
        continue;
928
72.7k
      }
929
87.0k
    else if( b0 == 0xffffffffUL )
930
50.1k
      {
931
        /* byte[1..3] have invalid character(s).  Switch to slow
932
           path.  */
933
50.1k
        skip_fast = 1;
934
50.1k
      }
935
36.8k
    else if( b1 == 0xffffffffUL )
936
24.9k
      {
937
        /* byte[4..7] have invalid character(s), first 4 bytes are
938
           valid.  */
939
24.9k
        buf[n + 0] = b0 >> (2 * 8);
940
24.9k
        buf[n + 1] = b0 >> (1 * 8);
941
24.9k
        buf[n + 2] = b0 >> (0 * 8);
942
24.9k
        afx->buffer_pos += 4 - 1;
943
24.9k
        n += 3;
944
24.9k
        skip_fast = 1;
945
24.9k
        continue;
946
24.9k
      }
947
11.8k
    else if( b2 == 0xffffffffUL )
948
6.97k
      {
949
        /* byte[8..11] have invalid character(s), first 8 bytes are
950
           valid.  */
951
6.97k
        buf[n + 0] = b0 >> (2 * 8);
952
6.97k
        buf[n + 1] = b0 >> (1 * 8);
953
6.97k
        buf[n + 2] = b0 >> (0 * 8);
954
6.97k
        buf[n + 3] = b1 >> (2 * 8);
955
6.97k
        buf[n + 4] = b1 >> (1 * 8);
956
6.97k
        buf[n + 5] = b1 >> (0 * 8);
957
6.97k
        afx->buffer_pos += 8 - 1;
958
6.97k
        n += 6;
959
6.97k
        skip_fast = 1;
960
6.97k
        continue;
961
6.97k
      }
962
4.87k
    else /*if( b3 == 0xffffffffUL )*/
963
4.87k
      {
964
        /* byte[12..15] have invalid character(s), first 12 bytes
965
           are valid.  */
966
4.87k
        buf[n + 0] = b0 >> (2 * 8);
967
4.87k
        buf[n + 1] = b0 >> (1 * 8);
968
4.87k
        buf[n + 2] = b0 >> (0 * 8);
969
4.87k
        buf[n + 3] = b1 >> (2 * 8);
970
4.87k
        buf[n + 4] = b1 >> (1 * 8);
971
4.87k
        buf[n + 5] = b1 >> (0 * 8);
972
4.87k
        buf[n + 6] = b2 >> (2 * 8);
973
4.87k
        buf[n + 7] = b2 >> (1 * 8);
974
4.87k
        buf[n + 8] = b2 >> (0 * 8);
975
4.87k
        afx->buffer_pos += 12 - 1;
976
4.87k
        n += 9;
977
4.87k
        skip_fast = 1;
978
4.87k
        continue;
979
4.87k
      }
980
159k
        }
981
982
704k
      switch(idx)
983
704k
        {
984
183k
    case 0: val =  binc << 2; break;
985
177k
    case 1: val |= (binc>>4)&3; buf[n++]=val;val=(binc<<4)&0xf0;break;
986
172k
    case 2: val |= (binc>>2)&15; buf[n++]=val;val=(binc<<6)&0xc0;break;
987
171k
    case 3: val |= binc&0x3f; buf[n++] = val; break;
988
704k
        }
989
704k
      idx = (idx+1) % 4;
990
991
704k
      continue;
992
704k
    }
993
994
1.24M
  skip_fast = 0;
995
996
1.24M
  if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
997
413k
      continue;
998
826k
  else if( c == '=' ) { /* pad character: stop */
999
      /* some mailers leave quoted-printable encoded characters
1000
       * so we try to workaround this */
1001
22.2k
      if( afx->buffer_pos+2 < afx->buffer_len ) {
1002
11.1k
    int cc1, cc2, cc3;
1003
11.1k
    cc1 = afx->buffer[afx->buffer_pos];
1004
11.1k
    cc2 = afx->buffer[afx->buffer_pos+1];
1005
11.1k
    cc3 = afx->buffer[afx->buffer_pos+2];
1006
11.1k
    if( isxdigit(cc1) && isxdigit(cc2)
1007
4.72k
          && strchr( "=\n\r\t ", cc3 )) {
1008
        /* well it seems to be the case - adjust */
1009
4.43k
        c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
1010
4.43k
        c <<= 4;
1011
4.43k
        c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
1012
4.43k
        afx->buffer_pos += 2;
1013
4.43k
        afx->qp_detected = 1;
1014
4.43k
        goto again;
1015
4.43k
    }
1016
11.1k
      }
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
17.8k
            if (afx->buffer_pos + 6 < afx->buffer_len
1024
953
                && afx->buffer[afx->buffer_pos + 0] == '3'
1025
38
                && afx->buffer[afx->buffer_pos + 1] == 'D'
1026
30
                && asctobin[0][afx->buffer[afx->buffer_pos + 2]] != 0xffffffffUL
1027
28
                && asctobin[0][afx->buffer[afx->buffer_pos + 3]] != 0xffffffffUL
1028
23
                && asctobin[0][afx->buffer[afx->buffer_pos + 4]] != 0xffffffffUL
1029
17
                && asctobin[0][afx->buffer[afx->buffer_pos + 5]] != 0xffffffffUL
1030
14
                && 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
17.8k
      if (!n)
1037
9.50k
        onlypad = 1;
1038
1039
17.8k
      if( idx == 1 )
1040
6.10k
    buf[n++] = val;
1041
17.8k
      checkcrc++;
1042
17.8k
      break;
1043
22.2k
  }
1044
804k
        else if (afx->buffer_pos == 1 && c == '-'
1045
21.1k
                 && afx->buffer_len > 9
1046
13.7k
                 && !strncmp (afx->buffer, "-----END ", 9)) {
1047
257
            break; /* End in --dearmor mode or No CRC.  */
1048
257
        }
1049
804k
  else {
1050
804k
      log_error(_("invalid radix64 character %02X skipped\n"), c);
1051
804k
      continue;
1052
804k
  }
1053
1.24M
    }
1054
1055
20.0k
    afx->idx = idx;
1056
20.0k
    afx->radbuf[0] = val;
1057
1058
20.0k
    if( n )
1059
13.9k
      {
1060
13.9k
        gcry_md_write (afx->crc_md, buf, n);
1061
13.9k
        afx->any_data = 1;
1062
13.9k
      }
1063
1064
20.0k
    if( checkcrc ) {
1065
17.8k
  gcry_md_final (afx->crc_md);
1066
17.8k
  afx->inp_checked=0;
1067
17.8k
  afx->faked = 0;
1068
30.1k
  for(;;) { /* skip lf and pad characters */
1069
30.1k
      if( afx->buffer_pos < afx->buffer_len )
1070
24.3k
    c = afx->buffer[afx->buffer_pos++];
1071
5.81k
      else { /* read the next line */
1072
5.81k
    unsigned maxlen = MAX_LINELEN;
1073
5.81k
    afx->buffer_pos = 0;
1074
5.81k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1075
5.81k
               &afx->buffer_size, &maxlen );
1076
5.81k
    if( !maxlen )
1077
0
        afx->truncated++;
1078
5.81k
    if( !afx->buffer_len )
1079
75
        break; /* eof */
1080
5.73k
    continue;
1081
5.81k
      }
1082
24.3k
      if( c == '\n' || c == ' ' || c == '\r'
1083
18.3k
    || c == '\t' || c == '=' )
1084
6.60k
    continue;
1085
17.7k
      break;
1086
24.3k
  }
1087
17.8k
  if( !afx->buffer_len )
1088
17.8k
      log_error(_("premature eof (no CRC)\n"));
1089
17.7k
  else {
1090
17.7k
      u32 mycrc = 0;
1091
17.7k
      idx = 0;
1092
20.6k
      do {
1093
20.6k
    if( (binc = asctobin[0][c]) == 0xffffffffUL )
1094
16.7k
        break;
1095
3.89k
    switch(idx) {
1096
1.08k
      case 0: val =  binc << 2; break;
1097
962
      case 1: val |= (binc>>4)&3; mycrc |= val << 16;val=(binc<<4)&0xf0;break;
1098
939
      case 2: val |= (binc>>2)&15; mycrc |= val << 8;val=(binc<<6)&0xc0;break;
1099
910
      case 3: val |= binc&0x3f; mycrc |= val; break;
1100
3.89k
    }
1101
3.89k
    for(;;) {
1102
3.89k
        if( afx->buffer_pos < afx->buffer_len )
1103
3.79k
      c = afx->buffer[afx->buffer_pos++];
1104
96
        else { /* read the next line */
1105
96
      unsigned maxlen = MAX_LINELEN;
1106
96
      afx->buffer_pos = 0;
1107
96
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1108
96
                 &afx->buffer_size,
1109
96
                &maxlen );
1110
96
      if( !maxlen )
1111
0
          afx->truncated++;
1112
96
      if( !afx->buffer_len )
1113
96
          break; /* eof */
1114
0
      continue;
1115
96
        }
1116
3.79k
        break;
1117
3.89k
    }
1118
3.89k
    if( !afx->buffer_len )
1119
96
        break; /* eof */
1120
3.89k
      } while( ++idx < 4 );
1121
17.7k
      if( !afx->buffer_len ) {
1122
96
    log_info(_("premature eof (in CRC)\n"));
1123
96
    rc = invalid_crc();
1124
96
      }
1125
17.6k
      else if( idx == 0 ) {
1126
          /* No CRC at all is legal ("MAY") */
1127
16.7k
          rc=0;
1128
16.7k
      }
1129
984
      else if( idx != 4 ) {
1130
74
    log_info(_("malformed CRC\n"));
1131
74
    rc = invalid_crc();
1132
74
      }
1133
910
      else if( mycrc != get_afx_crc (afx) ) {
1134
106
    log_info (_("CRC error; %06lX - %06lX\n"),
1135
106
            (ulong)get_afx_crc (afx), (ulong)mycrc);
1136
106
    rc = invalid_crc();
1137
106
      }
1138
804
      else {
1139
804
    rc = 0;
1140
                /* FIXME: Here we should emit another control packet,
1141
                 * so that we know in mainproc that we are processing
1142
                 * a clearsign message */
1143
#if 0
1144
    for(rc=0;!rc;) {
1145
        rc = 0 /*check_trailer( &fhdr, c )*/;
1146
        if( !rc ) {
1147
      if( (c=iobuf_get(a)) == -1 )
1148
          rc = 2;
1149
        }
1150
    }
1151
    if( rc == -1 )
1152
        rc = 0;
1153
    else if( rc == 2 ) {
1154
        log_error(_("premature eof (in trailer)\n"));
1155
        rc = GPG_ERR_INV_ARMOR;
1156
    }
1157
    else {
1158
        log_error(_("error in trailer line\n"));
1159
        rc = GPG_ERR_INV_ARMOR;
1160
    }
1161
#endif
1162
804
      }
1163
17.7k
  }
1164
17.8k
    }
1165
1166
20.0k
    if( !n && !onlypad )
1167
1.18k
  rc = -1;
1168
1169
20.0k
    *retn = n;
1170
20.0k
    return rc;
1171
20.0k
}
1172
1173
static void
1174
armor_output_buf_as_radix64 (armor_filter_context_t *afx, IOBUF a,
1175
           byte *buf, size_t size)
1176
0
{
1177
0
  byte radbuf[sizeof (afx->radbuf)];
1178
0
  byte outbuf[64 + sizeof (afx->eol)];
1179
0
  unsigned int eollen = strlen (afx->eol);
1180
0
  u32 in, in2;
1181
0
  int idx, idx2;
1182
0
  int i;
1183
1184
0
  idx = afx->idx;
1185
0
  idx2 = afx->idx2;
1186
0
  memcpy (radbuf, afx->radbuf, sizeof (afx->radbuf));
1187
1188
0
  if (size && (idx || idx2))
1189
0
    {
1190
      /* preload eol to outbuf buffer */
1191
0
      memcpy (outbuf + 4, afx->eol, sizeof (afx->eol));
1192
1193
0
      for (; size && (idx || idx2); buf++, size--)
1194
0
  {
1195
0
    radbuf[idx++] = *buf;
1196
0
    if (idx > 2)
1197
0
      {
1198
0
        idx = 0;
1199
0
        in = (u32)radbuf[0] << (2 * 8);
1200
0
        in |= (u32)radbuf[1] << (1 * 8);
1201
0
        in |= (u32)radbuf[2] << (0 * 8);
1202
0
        outbuf[0] = bintoasc[(in >> 18) & 077];
1203
0
        outbuf[1] = bintoasc[(in >> 12) & 077];
1204
0
        outbuf[2] = bintoasc[(in >> 6) & 077];
1205
0
        outbuf[3] = bintoasc[(in >> 0) & 077];
1206
0
        if (++idx2 >= (64/4))
1207
0
    { /* pgp doesn't like 72 here */
1208
0
      idx2=0;
1209
0
      iobuf_write (a, outbuf, 4 + eollen);
1210
0
    }
1211
0
        else
1212
0
    {
1213
0
      iobuf_write (a, outbuf, 4);
1214
0
    }
1215
0
      }
1216
0
  }
1217
0
    }
1218
1219
0
  if (size >= (64/4)*3)
1220
0
    {
1221
      /* preload eol to outbuf buffer */
1222
0
      memcpy (outbuf + 64, afx->eol, sizeof(afx->eol));
1223
1224
0
      do
1225
0
  {
1226
    /* idx and idx2 == 0 */
1227
1228
0
    for (i = 0; i < (64/8); i++)
1229
0
      {
1230
0
        in = (u32)buf[0] << (2 * 8);
1231
0
        in |= (u32)buf[1] << (1 * 8);
1232
0
        in |= (u32)buf[2] << (0 * 8);
1233
0
        in2 = (u32)buf[3] << (2 * 8);
1234
0
        in2 |= (u32)buf[4] << (1 * 8);
1235
0
        in2 |= (u32)buf[5] << (0 * 8);
1236
0
        outbuf[i*8+0] = bintoasc[(in >> 18) & 077];
1237
0
        outbuf[i*8+1] = bintoasc[(in >> 12) & 077];
1238
0
        outbuf[i*8+2] = bintoasc[(in >> 6) & 077];
1239
0
        outbuf[i*8+3] = bintoasc[(in >> 0) & 077];
1240
0
        outbuf[i*8+4] = bintoasc[(in2 >> 18) & 077];
1241
0
        outbuf[i*8+5] = bintoasc[(in2 >> 12) & 077];
1242
0
        outbuf[i*8+6] = bintoasc[(in2 >> 6) & 077];
1243
0
        outbuf[i*8+7] = bintoasc[(in2 >> 0) & 077];
1244
0
        buf+=6;
1245
0
        size-=6;
1246
0
      }
1247
1248
    /* pgp doesn't like 72 here */
1249
0
    iobuf_write (a, outbuf, 64 + eollen);
1250
0
  }
1251
0
      while (size >= (64/4)*3);
1252
1253
      /* restore eol for tail handling */
1254
0
      if (size)
1255
0
  memcpy (outbuf + 4, afx->eol, sizeof (afx->eol));
1256
0
    }
1257
1258
0
  for (; size; buf++, size--)
1259
0
    {
1260
0
      radbuf[idx++] = *buf;
1261
0
      if (idx > 2)
1262
0
  {
1263
0
    idx = 0;
1264
0
    in = (u32)radbuf[0] << (2 * 8);
1265
0
    in |= (u32)radbuf[1] << (1 * 8);
1266
0
    in |= (u32)radbuf[2] << (0 * 8);
1267
0
    outbuf[0] = bintoasc[(in >> 18) & 077];
1268
0
    outbuf[1] = bintoasc[(in >> 12) & 077];
1269
0
    outbuf[2] = bintoasc[(in >> 6) & 077];
1270
0
    outbuf[3] = bintoasc[(in >> 0) & 077];
1271
0
    if (++idx2 >= (64/4))
1272
0
      { /* pgp doesn't like 72 here */
1273
0
        idx2=0;
1274
0
        iobuf_write (a, outbuf, 4 + eollen);
1275
0
      }
1276
0
    else
1277
0
      {
1278
0
        iobuf_write (a, outbuf, 4);
1279
0
      }
1280
0
  }
1281
0
    }
1282
1283
0
  memcpy (afx->radbuf, radbuf, sizeof (afx->radbuf));
1284
0
  afx->idx = idx;
1285
0
  afx->idx2 = idx2;
1286
0
}
1287
1288
/****************
1289
 * This filter is used to handle the armor stuff
1290
 */
1291
static int
1292
armor_filter( void *opaque, int control,
1293
       IOBUF a, byte *buf, size_t *ret_len)
1294
42.2k
{
1295
42.2k
    size_t size = *ret_len;
1296
42.2k
    armor_filter_context_t *afx = opaque;
1297
42.2k
    int rc=0, c;
1298
42.2k
    byte radbuf[3];
1299
42.2k
    int  idx, idx2;
1300
42.2k
    size_t n=0;
1301
42.2k
    u32 crc;
1302
#if 0
1303
    static FILE *fp ;
1304
1305
    if( !fp ) {
1306
  fp = fopen("armor.out", "w");
1307
  log_assert(fp);
1308
    }
1309
#endif
1310
1311
42.2k
    if( DBG_FILTER )
1312
42.2k
  log_debug("armor-filter: control: %d\n", control );
1313
42.2k
    if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
1314
988
  n = 0;
1315
988
  if( afx->buffer_len ) {
1316
            /* Copy the data from AFX->BUFFER to BUF.  */
1317
327k
            for(; n < size && afx->buffer_pos < afx->buffer_len;)
1318
326k
                buf[n++] = afx->buffer[afx->buffer_pos++];
1319
194
      if( afx->buffer_pos >= afx->buffer_len )
1320
108
    afx->buffer_len = 0;
1321
194
  }
1322
        /* If there is still space in BUF, read directly into it.  */
1323
6.01M
  for(; n < size; n++ ) {
1324
6.01M
      if( (c=iobuf_get(a)) == -1 )
1325
392
    break;
1326
6.01M
      buf[n] = c & 0xff;
1327
6.01M
  }
1328
988
  if( !n )
1329
            /* We didn't get any data.  EOF.  */
1330
223
      rc = -1;
1331
988
  *ret_len = n;
1332
988
    }
1333
41.3k
    else if( control == IOBUFCTRL_UNDERFLOW ) {
1334
        /* We need some space for the faked packet.  The minimum
1335
         * required size is the PARTIAL_CHUNK size plus a byte for the
1336
         * length itself */
1337
34.7k
  if( size < PARTIAL_CHUNK+1 )
1338
0
      BUG(); /* supplied buffer too short */
1339
1340
34.7k
  if( afx->faked )
1341
7.29k
      rc = fake_packet( afx, a, &n, buf, size );
1342
27.4k
  else if( !afx->inp_checked ) {
1343
20.5k
      rc = check_input( afx, a );
1344
20.5k
      if( afx->inp_bypass ) {
1345
440k
    for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
1346
439k
        buf[n++] = afx->buffer[afx->buffer_pos++];
1347
292
    if( afx->buffer_pos >= afx->buffer_len )
1348
175
        afx->buffer_len = 0;
1349
292
    if( !n )
1350
22
        rc = -1;
1351
292
      }
1352
20.2k
      else if( afx->faked ) {
1353
7.10k
          unsigned int hashes = afx->hashes;
1354
7.10k
                const byte *sesmark;
1355
7.10k
                size_t sesmarklen;
1356
1357
7.10k
                sesmark = get_session_marker( &sesmarklen );
1358
7.10k
                if ( sesmarklen > 20 )
1359
0
                    BUG();
1360
1361
    /* the buffer is at least 15+n*15 bytes long, so it
1362
     * is easy to construct the packets */
1363
1364
7.10k
    hashes &= 1|2|8|16|32|64;
1365
7.10k
    if( !hashes ) {
1366
5.14k
        hashes |= 2;  /* Default to SHA-1. */
1367
5.14k
    }
1368
7.10k
    n=0;
1369
                /* First a gpg control packet... */
1370
7.10k
                buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1371
7.10k
                n++;   /* see below */
1372
7.10k
                memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1373
7.10k
                buf[n++] = CTRLPKT_CLEARSIGN_START;
1374
7.10k
                buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1375
7.10k
                if( hashes & 1 )
1376
1.58k
                    buf[n++] = DIGEST_ALGO_RMD160;
1377
7.10k
                if( hashes & 2 )
1378
7.02k
                    buf[n++] = DIGEST_ALGO_SHA1;
1379
7.10k
                if( hashes & 8 )
1380
211
                    buf[n++] = DIGEST_ALGO_SHA224;
1381
7.10k
                if( hashes & 16 )
1382
294
                    buf[n++] = DIGEST_ALGO_SHA256;
1383
7.10k
                if( hashes & 32 )
1384
33
                    buf[n++] = DIGEST_ALGO_SHA384;
1385
7.10k
                if( hashes & 64 )
1386
290
                    buf[n++] = DIGEST_ALGO_SHA512;
1387
7.10k
                buf[1] = n - 2;
1388
1389
    /* ...followed by an invented plaintext packet.
1390
       Amusingly enough, this packet is not compliant with
1391
       2440 as the initial partial length is less than 512
1392
       bytes.  Of course, we'll accept it anyway ;) */
1393
1394
7.10k
    buf[n++] = 0xCB; /* new packet format, type 11 */
1395
7.10k
    buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1396
7.10k
    buf[n++] = 't';  /* canonical text mode */
1397
7.10k
    buf[n++] = 0;  /* namelength */
1398
7.10k
    buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1399
7.10k
    memset(buf+n, 0, 4); /* timestamp */
1400
7.10k
    n += 4;
1401
7.10k
      }
1402
13.1k
      else if( !rc )
1403
13.0k
    rc = radix64_read( afx, a, &n, buf, size );
1404
20.5k
  }
1405
6.92k
  else
1406
6.92k
      rc = radix64_read( afx, a, &n, buf, size );
1407
#if 0
1408
  if( n )
1409
      if( fwrite(buf, n, 1, fp ) != 1 )
1410
    BUG();
1411
#endif
1412
34.7k
  *ret_len = n;
1413
34.7k
    }
1414
6.54k
    else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
1415
0
  if( !afx->status ) { /* write the header line */
1416
0
      const char *s;
1417
0
      strlist_t comment=opt.comments;
1418
1419
0
      if( afx->what >= DIM(head_strings) )
1420
0
    log_bug("afx->what=%d", afx->what);
1421
0
      iobuf_writestr(a, "-----");
1422
0
      iobuf_writestr(a, head_strings[afx->what] );
1423
0
      iobuf_writestr(a, "-----" );
1424
0
      iobuf_writestr(a,afx->eol);
1425
0
      if (opt.emit_version)
1426
0
        {
1427
0
    iobuf_writestr (a, "Version: "GNUPG_NAME" v");
1428
0
                for (s=VERSION; *s && *s != '.'; s++)
1429
0
                  iobuf_writebyte (a, *s);
1430
0
                if (opt.emit_version > 1 && *s)
1431
0
                  {
1432
0
                    iobuf_writebyte (a, *s++);
1433
0
                    for (; *s && *s != '.'; s++)
1434
0
                      iobuf_writebyte (a, *s);
1435
0
                    if (opt.emit_version > 2)
1436
0
                      {
1437
0
                        for (; *s && *s != '-' && !spacep (s); s++)
1438
0
                          iobuf_writebyte (a, *s);
1439
0
                        if (opt.emit_version > 3)
1440
0
                          iobuf_writestr (a, " (" PRINTABLE_OS_NAME ")");
1441
0
                      }
1442
0
                  }
1443
0
    iobuf_writestr(a,afx->eol);
1444
0
        }
1445
1446
      /* write the comment strings */
1447
0
      for(;comment;comment=comment->next)
1448
0
        {
1449
0
    iobuf_writestr(a, "Comment: " );
1450
0
    for( s=comment->d; *s; s++ )
1451
0
      {
1452
0
        if( *s == '\n' )
1453
0
          iobuf_writestr(a, "\\n" );
1454
0
        else if( *s == '\r' )
1455
0
          iobuf_writestr(a, "\\r" );
1456
0
        else if( *s == '\v' )
1457
0
          iobuf_writestr(a, "\\v" );
1458
0
        else
1459
0
          iobuf_put(a, *s );
1460
0
      }
1461
1462
0
    iobuf_writestr(a,afx->eol);
1463
0
        }
1464
1465
0
      if ( afx->hdrlines ) {
1466
0
                for ( s = afx->hdrlines; *s; s++ ) {
1467
#ifdef HAVE_DOSISH_SYSTEM
1468
                    if ( *s == '\n' )
1469
                        iobuf_put( a, '\r');
1470
#endif
1471
0
                    iobuf_put(a, *s );
1472
0
                }
1473
0
            }
1474
1475
0
      iobuf_writestr(a,afx->eol);
1476
0
      afx->status++;
1477
0
      afx->idx = 0;
1478
0
      afx->idx2 = 0;
1479
0
      gcry_md_reset (afx->crc_md);
1480
0
  }
1481
1482
0
  if( size ) {
1483
0
      gcry_md_write (afx->crc_md, buf, size);
1484
0
      armor_output_buf_as_radix64 (afx, a, buf, size);
1485
0
        }
1486
0
    }
1487
6.54k
    else if( control == IOBUFCTRL_INIT )
1488
3.27k
      {
1489
3.27k
  if( !is_initialized )
1490
1
    initialize();
1491
1492
  /* Figure out what we're using for line endings if the caller
1493
     didn't specify. */
1494
3.27k
  if(afx->eol[0]==0)
1495
3.27k
    {
1496
#ifdef HAVE_DOSISH_SYSTEM
1497
      afx->eol[0]='\r';
1498
      afx->eol[1]='\n';
1499
#else
1500
3.27k
      afx->eol[0]='\n';
1501
3.27k
#endif
1502
3.27k
    }
1503
3.27k
      }
1504
3.27k
    else if( control == IOBUFCTRL_CANCEL ) {
1505
0
  afx->cancel = 1;
1506
0
    }
1507
3.27k
    else if( control == IOBUFCTRL_FREE ) {
1508
3.27k
  if( afx->cancel )
1509
0
      ;
1510
3.27k
  else if( afx->status ) { /* pad, write checksum, and bottom line */
1511
0
      gcry_md_final (afx->crc_md);
1512
0
      crc = get_afx_crc (afx);
1513
0
      idx = afx->idx;
1514
0
      idx2 = afx->idx2;
1515
0
      if( idx ) {
1516
0
    c = bintoasc[(afx->radbuf[0]>>2)&077];
1517
0
    iobuf_put(a, c);
1518
0
    if( idx == 1 ) {
1519
0
        c = bintoasc[((afx->radbuf[0] << 4) & 060) & 077];
1520
0
        iobuf_put(a, c);
1521
0
        iobuf_put(a, '=');
1522
0
        iobuf_put(a, '=');
1523
0
    }
1524
0
    else { /* 2 */
1525
0
        c = bintoasc[(((afx->radbuf[0]<<4)&060)
1526
0
                                  |((afx->radbuf[1]>>4)&017))&077];
1527
0
        iobuf_put(a, c);
1528
0
        c = bintoasc[((afx->radbuf[1] << 2) & 074) & 077];
1529
0
        iobuf_put(a, c);
1530
0
        iobuf_put(a, '=');
1531
0
    }
1532
0
    if( ++idx2 >= (64/4) )
1533
0
      { /* pgp doesn't like 72 here */
1534
0
        iobuf_writestr(a,afx->eol);
1535
0
        idx2=0;
1536
0
      }
1537
0
      }
1538
      /* may need a linefeed */
1539
0
      if( idx2 )
1540
0
        iobuf_writestr(a,afx->eol);
1541
      /* write the CRC */
1542
0
      iobuf_put(a, '=');
1543
0
      radbuf[0] = crc >>16;
1544
0
      radbuf[1] = crc >> 8;
1545
0
      radbuf[2] = crc;
1546
0
      c = bintoasc[(*radbuf >> 2) & 077];
1547
0
      iobuf_put(a, c);
1548
0
      c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1549
0
      iobuf_put(a, c);
1550
0
      c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1551
0
      iobuf_put(a, c);
1552
0
      c = bintoasc[radbuf[2]&077];
1553
0
      iobuf_put(a, c);
1554
0
      iobuf_writestr(a,afx->eol);
1555
      /* and the trailer */
1556
0
      if( afx->what >= DIM(tail_strings) )
1557
0
    log_bug("afx->what=%d", afx->what);
1558
0
      iobuf_writestr(a, "-----");
1559
0
      iobuf_writestr(a, tail_strings[afx->what] );
1560
0
      iobuf_writestr(a, "-----" );
1561
0
      iobuf_writestr(a,afx->eol);
1562
0
  }
1563
3.27k
  else if( !afx->any_data && !afx->inp_bypass ) {
1564
1.77k
      log_error(_("no valid OpenPGP data found.\n"));
1565
1.77k
      afx->no_openpgp_data = 1;
1566
1.77k
      write_status_text( STATUS_NODATA, "1" );
1567
1.77k
  }
1568
        /* Note that in a cleartext signature truncated lines in the
1569
         * plaintext are detected and propagated to the signature
1570
         * checking code by inserting a \f into the plaintext.  We do
1571
         * not use log_info here because some of the truncated lines
1572
         * are harmless.  */
1573
3.27k
  if( afx->truncated )
1574
3.27k
      log_info(_("invalid armor: line longer than %d characters\n"),
1575
26
          MAX_LINELEN );
1576
  /* issue an error to enforce dissemination of correct software */
1577
3.27k
  if( afx->qp_detected )
1578
3.27k
      log_error(_("quoted printable character in armor - "
1579
67
      "probably a buggy MTA has been used\n") );
1580
3.27k
  xfree( afx->buffer );
1581
3.27k
  afx->buffer = NULL;
1582
3.27k
        release_armor_context (afx);
1583
3.27k
    }
1584
0
    else if( control == IOBUFCTRL_DESC )
1585
0
        mem2str (buf, "armor_filter", *ret_len);
1586
42.2k
    return rc;
1587
42.2k
}
1588
1589
1590
/****************
1591
 * create a radix64 encoded string.
1592
 */
1593
char *
1594
make_radix64_string( const byte *data, size_t len )
1595
0
{
1596
0
    char *buffer, *p;
1597
1598
0
    buffer = p = xmalloc( (len+2)/3*4 + 1 );
1599
0
    for( ; len >= 3 ; len -= 3, data += 3 ) {
1600
0
  *p++ = bintoasc[(data[0] >> 2) & 077];
1601
0
  *p++ = bintoasc[(((data[0] <<4)&060)|((data[1] >> 4)&017))&077];
1602
0
  *p++ = bintoasc[(((data[1]<<2)&074)|((data[2]>>6)&03))&077];
1603
0
  *p++ = bintoasc[data[2]&077];
1604
0
    }
1605
0
    if( len == 2 ) {
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)];
1609
0
    }
1610
0
    else if( len == 1 ) {
1611
0
  *p++ = bintoasc[(data[0] >> 2) & 077];
1612
0
  *p++ = bintoasc[(data[0] <<4)&060];
1613
0
    }
1614
0
    *p = 0;
1615
0
    return buffer;
1616
0
}