Coverage Report

Created: 2026-06-07 06:25

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.59M
#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
13.0k
#define BEGIN_SIGNATURE 2
83
48.6k
#define BEGIN_SIGNED_MSG_IDX 3
84
static char *head_strings[] = {
85
    "BEGIN PGP MESSAGE",
86
    "BEGIN PGP PUBLIC KEY BLOCK",
87
    "BEGIN PGP SIGNATURE",
88
    "BEGIN PGP SIGNED MESSAGE",
89
    "BEGIN PGP ARMORED FILE",       /* gnupg extension */
90
    "BEGIN PGP PRIVATE KEY BLOCK",
91
    "BEGIN PGP SECRET KEY BLOCK",   /* only used by pgp2 */
92
    NULL
93
};
94
static char *tail_strings[] = {
95
    "END PGP MESSAGE",
96
    "END PGP PUBLIC KEY BLOCK",
97
    "END PGP SIGNATURE",
98
    "END dummy",
99
    "END PGP ARMORED FILE",
100
    "END PGP PRIVATE KEY BLOCK",
101
    "END PGP SECRET KEY BLOCK",
102
    NULL
103
};
104
105
106
static int armor_filter ( void *opaque, int control,
107
                          iobuf_t chain, byte *buf, size_t *ret_len);
108
109
110
111

112
/* Create a new context for armor filters.  */
113
armor_filter_context_t *
114
new_armor_context (void)
115
12.1k
{
116
12.1k
  armor_filter_context_t *afx;
117
12.1k
  gpg_error_t err;
118
119
12.1k
  afx = xcalloc (1, sizeof *afx);
120
12.1k
  if (afx)
121
12.1k
    {
122
12.1k
      err = gcry_md_open (&afx->crc_md, GCRY_MD_CRC24_RFC2440, 0);
123
12.1k
      if (err != 0)
124
0
  {
125
0
    log_error ("gcry_md_open failed for GCRY_MD_CRC24_RFC2440: %s",
126
0
        gpg_strerror (err));
127
0
    xfree (afx);
128
0
    return NULL;
129
0
  }
130
131
12.1k
      afx->refcount = 1;
132
12.1k
    }
133
134
12.1k
  return afx;
135
12.1k
}
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
39.2k
{
142
39.2k
  if (!afx)
143
14.8k
    return;
144
39.2k
  log_assert (afx->refcount);
145
24.3k
  if ( --afx->refcount )
146
12.1k
    return;
147
12.1k
  gcry_md_close (afx->crc_md);
148
12.1k
  xfree (afx);
149
12.1k
}
150
151
/* Push the armor filter onto the iobuf stream IOBUF.  */
152
int
153
push_armor_filter (armor_filter_context_t *afx, iobuf_t iobuf)
154
12.1k
{
155
12.1k
  int rc;
156
157
12.1k
  afx->refcount++;
158
12.1k
  rc = iobuf_push_filter (iobuf, armor_filter, afx);
159
12.1k
  if (rc)
160
0
    afx->refcount--;
161
12.1k
  return rc;
162
12.1k
}
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
4
{
179
4
    u32 i;
180
4
    const byte *s;
181
182
    /* Build the helptable for radix64 to bin conversion.  Value 0xffffffff is
183
       used to detect invalid characters.  */
184
4
    memset (asctobin, 0xff, sizeof(asctobin));
185
260
    for(s=bintoasc,i=0; *s; s++,i++ )
186
256
      {
187
256
  asctobin[0][*s] = i << (0 * 6);
188
256
  asctobin[1][*s] = i << (1 * 6);
189
256
  asctobin[2][*s] = i << (2 * 6);
190
256
  asctobin[3][*s] = i << (3 * 6);
191
256
      }
192
193
4
    is_initialized=1;
194
4
}
195
196
197
static inline u32
198
get_afx_crc (armor_filter_context_t *afx)
199
1.90k
{
200
1.90k
  const byte *crc_buf;
201
1.90k
  u32 crc;
202
203
1.90k
  crc_buf = gcry_md_read (afx->crc_md, GCRY_MD_CRC24_RFC2440);
204
205
1.90k
  crc = crc_buf[0];
206
1.90k
  crc <<= 8;
207
1.90k
  crc |= crc_buf[1];
208
1.90k
  crc <<= 8;
209
1.90k
  crc |= crc_buf[2];
210
211
1.90k
  return crc;
212
1.90k
}
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
73.8k
{
227
73.8k
  int ctb, pkttype;
228
73.8k
  int indeterminate_length_allowed;
229
230
73.8k
    ctb = *buf;
231
73.8k
    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
48.7k
      return 1;
236
237
25.1k
    pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
238
25.1k
    switch( pkttype ) {
239
690
      case PKT_PUBKEY_ENC:
240
5.55k
      case PKT_SIGNATURE:
241
6.15k
      case PKT_SYMKEY_ENC:
242
7.44k
      case PKT_ONEPASS_SIG:
243
8.23k
      case PKT_SECRET_KEY:
244
10.8k
      case PKT_PUBLIC_KEY:
245
11.9k
      case PKT_SECRET_SUBKEY:
246
12.2k
      case PKT_MARKER:
247
13.2k
      case PKT_RING_TRUST:
248
13.7k
      case PKT_USER_ID:
249
13.9k
      case PKT_PUBLIC_SUBKEY:
250
15.1k
      case PKT_ATTRIBUTE:
251
16.1k
      case PKT_MDC:
252
16.1k
  indeterminate_length_allowed = 0;
253
16.1k
        break;
254
255
2.73k
      case PKT_COMPRESSED:
256
3.24k
      case PKT_ENCRYPTED:
257
3.62k
      case PKT_ENCRYPTED_MDC:
258
3.99k
      case PKT_ENCRYPTED_AEAD:
259
5.57k
      case PKT_PLAINTEXT:
260
5.74k
      case PKT_OLD_COMMENT:
261
6.02k
      case PKT_COMMENT:
262
6.39k
      case PKT_GPG_CONTROL:
263
6.39k
  indeterminate_length_allowed = 1;
264
6.39k
        break;
265
266
2.58k
      default:
267
        /* Invalid packet type.  */
268
2.58k
        return 1;
269
25.1k
    }
270
271
22.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
16.1k
      {
277
16.1k
        int new_format;
278
16.1k
        int indeterminate_length;
279
280
16.1k
        new_format = !! (ctb & (1 << 6));
281
16.1k
        if (new_format)
282
7.43k
          indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
283
8.72k
        else
284
8.72k
          indeterminate_length = (ctb & 3) == 3;
285
286
16.1k
        if (indeterminate_length)
287
1.79k
          return 1;
288
16.1k
      }
289
290
    /* The first CTB seems legit.  It is probably not armored
291
       data.  */
292
20.7k
    return 0;
293
22.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
20.2k
{
304
20.2k
    byte buf[2];
305
20.2k
    int n;
306
307
    /* fixme: there might be a problem with iobuf_peek */
308
20.2k
    n = iobuf_peek (a, buf, 2);
309
20.2k
    if( n == -1 )
310
0
  return 0; /* EOF, doesn't matter whether armored or not */
311
20.2k
    if( !n )
312
0
  return 1; /* can't check it: try armored */
313
20.2k
    if (n != 2)
314
47
  return 0; /* short buffer */
315
20.1k
    return is_armored(buf);
316
20.2k
}
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
9.37k
{
339
9.37k
    const char *s, *s2;
340
9.37k
    unsigned found = 0;
341
342
9.37k
    if( strlen(line) < 6  || strlen(line) > 60 )
343
444
  return 0; /* too short or too long */
344
8.92k
    if( memcmp( line, "Hash:", 5 ) )
345
424
  return 0; /* invalid header */
346
347
22.1k
    for(s=line+5;;s=s2) {
348
30.7k
  for(; *s && (*s==' ' || *s == '\t'); s++ )
349
8.58k
      ;
350
22.1k
  if( !*s )
351
5.27k
      break;
352
55.5k
  for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
353
38.7k
      ;
354
16.8k
  if( !strncmp( s, "RIPEMD160", s2-s ) )
355
1.19k
      found |= 1;
356
15.6k
  else if( !strncmp( s, "SHA1", s2-s ) )
357
9.62k
      found |= 2;
358
6.02k
  else if( !strncmp( s, "SHA224", s2-s ) )
359
1.55k
      found |= 8;
360
4.47k
  else if( !strncmp( s, "SHA256", s2-s ) )
361
365
      found |= 16;
362
4.10k
  else if( !strncmp( s, "SHA384", s2-s ) )
363
232
      found |= 32;
364
3.87k
  else if( !strncmp( s, "SHA512", s2-s ) )
365
1.25k
      found |= 64;
366
2.62k
  else
367
2.62k
      return 0;
368
19.9k
  for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
369
5.75k
      ;
370
14.2k
  if( *s2 && *s2 != ',' )
371
603
      return 0;
372
13.6k
  if( *s2 )
373
8.35k
      s2++;
374
13.6k
    }
375
5.27k
    return found;
376
8.50k
}
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
13.3k
{
382
13.3k
  if(strncmp(line,"Version",7)==0
383
11.9k
     || strncmp(line,"Comment",7)==0
384
9.70k
     || strncmp(line,"MessageID",9)==0
385
7.64k
     || strncmp(line,"Hash",4)==0
386
6.74k
     || strncmp(line,"Charset",7)==0)
387
7.99k
    return 1;
388
389
5.39k
  return 0;
390
13.3k
}
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.03M
{
400
2.03M
    const char *s;
401
2.03M
    byte *save_p, *p;
402
2.03M
    int save_c;
403
2.03M
    int i;
404
405
2.03M
    if( len < 15 )
406
1.61M
  return -1; /* too short */
407
416k
    if( memcmp( line, "-----", 5 ) )
408
346k
  return -1; /* no */
409
70.8k
    p = strstr( line+5, "-----");
410
70.8k
    if( !p )
411
8.00k
  return -1;
412
62.8k
    save_p = p;
413
62.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
62.8k
    if(RFC2440)
424
0
      {
425
0
  if( *p == '\r' )
426
0
    p++;
427
0
  if( *p == '\n' )
428
0
    p++;
429
0
      }
430
62.8k
    else
431
126k
      while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
432
63.2k
  p++;
433
434
62.8k
    if( *p )
435
2.60k
  return -1; /* garbage after dashes */
436
60.1k
    save_c = *save_p; *save_p = 0;
437
60.1k
    p = line+5;
438
210k
    for(i=0; (s=head_strings[i]); i++ )
439
199k
  if( !strcmp(s, p) )
440
49.8k
      break;
441
60.1k
    *save_p = save_c;
442
60.1k
    if (!s)
443
10.3k
      {
444
10.3k
        if (!strncmp (p, "BEGIN ", 6))
445
5.74k
          return 42;
446
4.63k
  return -1; /* unknown armor line */
447
10.3k
      }
448
449
49.8k
    if( opt.verbose > 1 )
450
49.8k
  log_info(_("armor: %s\n"), head_strings[i]);
451
49.8k
    return i;
452
60.1k
}
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
80.0k
{
465
80.0k
    byte *p;
466
80.0k
    int hashes=0;
467
80.0k
    unsigned int len2;
468
469
80.0k
    len2 = length_sans_trailing_ws ( line, len );
470
80.0k
    if( !len2 ) {
471
32.9k
        afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
472
32.9k
  return 0; /* WS only: same as empty line */
473
32.9k
    }
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
47.1k
    p = strchr( line, ':');
486
47.1k
    if (!p && afx->dearmor_state)
487
0
      return 0; /* Special treatment in --dearmor mode.  */
488
47.1k
    if( !p || (RFC2440 && p[1]!=' ')
489
25.6k
  || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
490
24.3k
      {
491
24.3k
  log_error (_("invalid armor header: "));
492
24.3k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
493
24.3k
  log_printf ("\n");
494
24.3k
  return -1;
495
24.3k
      }
496
497
    /* Chop off the whitespace we detected before */
498
22.7k
    len=len2;
499
22.7k
    line[len2]='\0';
500
501
22.7k
    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
22.7k
    if (afx->dearmor_mode)
508
0
      ;
509
22.7k
    else if (afx->in_cleartext)
510
9.37k
      {
511
9.37k
  if( (hashes=parse_hash_header( line )) )
512
5.27k
    afx->hashes |= hashes;
513
4.09k
  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
4.09k
  else
518
4.09k
    {
519
4.09k
      log_error(_("invalid clearsig header\n"));
520
4.09k
      return -1;
521
4.09k
    }
522
9.37k
      }
523
13.3k
    else if(!is_armor_tag(line))
524
5.39k
      {
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
5.39k
  log_info(_("unknown armor header: "));
533
5.39k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
534
5.39k
  log_printf ("\n");
535
5.39k
      }
536
537
18.6k
    return 1;
538
22.7k
}
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
56.5k
{
546
56.5k
    int rc = 0;
547
56.5k
    int i;
548
56.5k
    byte *line;
549
56.5k
    unsigned len;
550
56.5k
    unsigned maxlen;
551
56.5k
    int hdr_line = -1;
552
553
    /* read the first line to see whether this is armored data */
554
56.5k
    maxlen = MAX_LINELEN;
555
56.5k
    len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
556
56.5k
               &afx->buffer_size, &maxlen );
557
56.5k
    line = afx->buffer;
558
56.5k
    if( !maxlen ) {
559
  /* line has been truncated: assume not armored */
560
39
  afx->inp_checked = 1;
561
39
  afx->inp_bypass = 1;
562
39
  return 0;
563
39
    }
564
565
56.5k
    if( !len ) {
566
159
  return -1; /* eof */
567
159
    }
568
569
    /* (the line is always a C string but maybe longer) */
570
56.3k
    if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
571
2.66k
  ;
572
53.7k
    else if (len >= 2 && !is_armored (line)) {
573
5.90k
  afx->inp_checked = 1;
574
5.90k
  afx->inp_bypass = 1;
575
5.90k
  return 0;
576
5.90k
    }
577
578
    /* find the armor header */
579
2.02M
    while(len) {
580
2.01M
  i = is_armor_header( line, len );
581
2.01M
        if ( i == 42 ) {
582
4.73k
            if (afx->dearmor_mode) {
583
0
                afx->dearmor_state = 1;
584
0
                break;
585
0
            }
586
4.73k
        }
587
2.01M
        else if (i >= 0
588
48.8k
                 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
589
48.6k
      hdr_line = i;
590
48.6k
      if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
591
13.9k
          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
13.9k
    afx->in_cleartext = 1;
596
13.9k
      }
597
48.6k
      break;
598
48.6k
  }
599
600
  /* read the next line (skip all truncated lines) */
601
1.97M
  do {
602
1.97M
      maxlen = MAX_LINELEN;
603
1.97M
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
604
1.97M
                 &afx->buffer_size, &maxlen );
605
1.97M
      line = afx->buffer;
606
1.97M
      len = afx->buffer_len;
607
1.97M
  } while( !maxlen );
608
1.97M
    }
609
610
    /* Parse the header lines.  */
611
68.2k
    while(len) {
612
  /* Read the next line (skip all truncated lines). */
613
66.4k
  do {
614
66.4k
      maxlen = MAX_LINELEN;
615
66.4k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
616
66.4k
                 &afx->buffer_size, &maxlen );
617
66.4k
      line = afx->buffer;
618
66.4k
      len = afx->buffer_len;
619
66.4k
  } while( !maxlen );
620
621
66.4k
  i = parse_header_line( afx, line, len );
622
66.4k
  if( i <= 0 ) {
623
48.6k
      if (i && RFC2440)
624
0
    rc = GPG_ERR_INV_ARMOR;
625
48.6k
      break;
626
48.6k
  }
627
66.4k
    }
628
629
630
50.4k
    if( rc )
631
0
  invalid_armor();
632
50.4k
    else if( afx->in_cleartext )
633
13.9k
  afx->faked = 1;
634
36.4k
    else {
635
36.4k
  afx->inp_checked = 1;
636
36.4k
  gcry_md_reset (afx->crc_md);
637
36.4k
  afx->idx = 0;
638
36.4k
  afx->radbuf[0] = 0;
639
36.4k
    }
640
641
50.4k
    return rc;
642
56.3k
}
643
644
15.4M
#define PARTIAL_CHUNK 512
645
7.96k
#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
14.0k
{
656
14.0k
    int rc = 0;
657
14.0k
    size_t len = 0;
658
14.0k
    int lastline = 0;
659
14.0k
    unsigned maxlen, n;
660
14.0k
    byte *p;
661
14.0k
    byte tempbuf[PARTIAL_CHUNK];
662
14.0k
    size_t tempbuf_len=0;
663
14.0k
    int this_truncated;
664
665
1.21M
    while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
666
  /* copy what we have in the line buffer */
667
1.19M
  if( afx->faked == 1 )
668
13.9k
      afx->faked++; /* skip the first (empty) line */
669
1.18M
  else
670
1.18M
    {
671
      /* It's full, so write this partial chunk */
672
1.18M
      if(tempbuf_len==PARTIAL_CHUNK)
673
7.96k
        {
674
7.96k
    buf[len++]=0xE0+PARTIAL_POW;
675
7.96k
    memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
676
7.96k
    len+=PARTIAL_CHUNK;
677
7.96k
    tempbuf_len=0;
678
7.96k
    continue;
679
7.96k
        }
680
681
5.91M
      while( tempbuf_len < PARTIAL_CHUNK
682
5.91M
       && afx->buffer_pos < afx->buffer_len )
683
4.74M
        tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
684
1.17M
      if( tempbuf_len==PARTIAL_CHUNK )
685
7.96k
        continue;
686
1.17M
    }
687
688
  /* read the next line */
689
1.18M
  maxlen = MAX_LINELEN;
690
1.18M
  afx->buffer_pos = 0;
691
1.18M
  afx->buffer_len = iobuf_read_line( a, &afx->buffer,
692
1.18M
             &afx->buffer_size, &maxlen );
693
1.18M
  if( !afx->buffer_len ) {
694
900
      rc = -1; /* eof (should not happen) */
695
900
      continue;
696
900
  }
697
1.18M
  if( !maxlen )
698
16
          {
699
16
      afx->truncated++;
700
16
            this_truncated = 1;
701
16
          }
702
1.18M
        else
703
1.18M
          this_truncated = 0;
704
705
706
1.18M
  p = afx->buffer;
707
1.18M
  n = afx->buffer_len;
708
709
  /* Armor header or dash-escaped line? */
710
1.18M
  if(p[0]=='-')
711
22.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
22.3k
      if(p[1]==' ' && !afx->not_dash_escaped)
719
629
        {
720
    /* It's a dash-escaped line, so skip over the
721
       escape. */
722
629
    afx->buffer_pos = 2;
723
629
        }
724
21.6k
      else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
725
13.0k
        {
726
    /* Five dashes in a row mean it's probably armor
727
       header. */
728
13.0k
    int type = is_armor_header( p, n );
729
13.0k
                if (type == 42)
730
1.00k
                  type = -1;  /* Only OpenPGP armors are expected.  */
731
13.0k
    if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
732
0
      ; /* this is okay */
733
13.0k
    else
734
13.0k
      {
735
13.0k
        if( type != BEGIN_SIGNATURE )
736
12.8k
          {
737
12.8k
      log_info(_("unexpected armor: "));
738
12.8k
      es_write_sanitized (log_get_stream (), p, n,
739
12.8k
                                            NULL, NULL);
740
12.8k
      log_printf ("\n");
741
12.8k
          }
742
743
13.0k
        lastline = 1;
744
13.0k
        rc = -1;
745
13.0k
      }
746
13.0k
        }
747
8.61k
      else if(!afx->not_dash_escaped)
748
8.61k
        {
749
    /* Bad dash-escaping. */
750
8.61k
    log_info (_("invalid dash escaped line: "));
751
8.61k
    es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
752
8.61k
    log_printf ("\n");
753
8.61k
        }
754
22.3k
    }
755
756
  /* Now handle the end-of-line canonicalization */
757
1.18M
  if( !afx->not_dash_escaped || this_truncated)
758
1.18M
    {
759
1.18M
      int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
760
761
1.18M
      afx->buffer_len=
762
1.18M
        trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
763
1.18M
           " \t\r\n");
764
1.18M
      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.18M
      if( crlf )
783
5.50k
        afx->buffer[afx->buffer_len++] = '\r';
784
1.18M
      afx->buffer[afx->buffer_len++] = this_truncated? '\f':'\n';
785
1.18M
      afx->buffer[afx->buffer_len] = '\0';
786
1.18M
    }
787
1.18M
    }
788
789
14.0k
    if( lastline ) { /* write last (ending) length header */
790
13.0k
        if(tempbuf_len<192)
791
11.8k
    buf[len++]=tempbuf_len;
792
1.17k
  else
793
1.17k
    {
794
1.17k
      buf[len++]=((tempbuf_len-192)/256) + 192;
795
1.17k
      buf[len++]=(tempbuf_len-192) % 256;
796
1.17k
    }
797
13.0k
  memcpy(&buf[len],tempbuf,tempbuf_len);
798
13.0k
  len+=tempbuf_len;
799
800
13.0k
  rc = 0;
801
13.0k
  afx->faked = 0;
802
13.0k
  afx->in_cleartext = 0;
803
  /* and now read the header lines */
804
13.0k
  afx->buffer_pos = 0;
805
13.9k
  for(;;) {
806
13.9k
      int i;
807
808
      /* read the next line (skip all truncated lines) */
809
13.9k
      do {
810
13.9k
    maxlen = MAX_LINELEN;
811
13.9k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
812
13.9k
             &afx->buffer_size, &maxlen );
813
13.9k
      } while( !maxlen );
814
13.9k
      p = afx->buffer;
815
13.9k
      n = afx->buffer_len;
816
13.9k
      if( !n ) {
817
350
    rc = -1;
818
350
    break; /* eof */
819
350
      }
820
13.6k
      i = parse_header_line( afx, p , n );
821
13.6k
      if( i <= 0 ) {
822
12.7k
    if( i )
823
0
        invalid_armor();
824
12.7k
    break;
825
12.7k
      }
826
13.6k
  }
827
13.0k
  afx->inp_checked = 1;
828
13.0k
  gcry_md_reset (afx->crc_md);
829
13.0k
  afx->idx = 0;
830
13.0k
  afx->radbuf[0] = 0;
831
13.0k
    }
832
833
14.0k
    *retn = len;
834
14.0k
    return rc;
835
14.0k
}
836
837
838
static int
839
invalid_crc(void)
840
490
{
841
490
  if ( opt.ignore_crc_error )
842
0
    return 0;
843
490
  log_inc_errorcount();
844
490
  return gpg_error (GPG_ERR_INV_ARMOR);
845
490
}
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
50.1k
{
852
50.1k
    byte val;
853
50.1k
    int c;
854
50.1k
    u32 binc;
855
50.1k
    int checkcrc=0;
856
50.1k
    int rc = 0;
857
50.1k
    size_t n = 0;
858
50.1k
    int idx, onlypad=0;
859
50.1k
    int skip_fast = 0;
860
861
50.1k
    idx = afx->idx;
862
50.1k
    val = afx->radbuf[0];
863
2.63M
    for( n=0; n < size; ) {
864
865
2.63M
  if( afx->buffer_pos < afx->buffer_len )
866
2.34M
      c = afx->buffer[afx->buffer_pos++];
867
290k
  else { /* read the next line */
868
290k
      unsigned maxlen = MAX_LINELEN;
869
290k
      afx->buffer_pos = 0;
870
290k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
871
290k
                 &afx->buffer_size, &maxlen );
872
290k
      if( !maxlen )
873
12
    afx->truncated++;
874
290k
      if( !afx->buffer_len )
875
4.36k
    break; /* eof */
876
286k
      continue;
877
290k
  }
878
879
2.34M
      again:
880
2.34M
  binc = asctobin[0][c];
881
882
2.34M
  if( binc != 0xffffffffUL )
883
1.05M
    {
884
1.05M
      if( idx == 0 && skip_fast == 0
885
406k
    && afx->buffer_pos + (16 - 1) < afx->buffer_len
886
278k
    && n + 12 < size)
887
277k
        {
888
    /* Fast path for radix64 to binary conversion.  */
889
277k
    u32 b0,b1,b2,b3;
890
891
    /* Speculatively load 15 more input bytes.  */
892
277k
    b0 = binc << (3 * 6);
893
277k
    b0 |= asctobin[2][afx->buffer[afx->buffer_pos + 0]];
894
277k
    b0 |= asctobin[1][afx->buffer[afx->buffer_pos + 1]];
895
277k
    b0 |= asctobin[0][afx->buffer[afx->buffer_pos + 2]];
896
277k
    b1  = asctobin[3][afx->buffer[afx->buffer_pos + 3]];
897
277k
    b1 |= asctobin[2][afx->buffer[afx->buffer_pos + 4]];
898
277k
    b1 |= asctobin[1][afx->buffer[afx->buffer_pos + 5]];
899
277k
    b1 |= asctobin[0][afx->buffer[afx->buffer_pos + 6]];
900
277k
    b2  = asctobin[3][afx->buffer[afx->buffer_pos + 7]];
901
277k
    b2 |= asctobin[2][afx->buffer[afx->buffer_pos + 8]];
902
277k
    b2 |= asctobin[1][afx->buffer[afx->buffer_pos + 9]];
903
277k
    b2 |= asctobin[0][afx->buffer[afx->buffer_pos + 10]];
904
277k
    b3  = asctobin[3][afx->buffer[afx->buffer_pos + 11]];
905
277k
    b3 |= asctobin[2][afx->buffer[afx->buffer_pos + 12]];
906
277k
    b3 |= asctobin[1][afx->buffer[afx->buffer_pos + 13]];
907
277k
    b3 |= asctobin[0][afx->buffer[afx->buffer_pos + 14]];
908
909
    /* Check if any of the input bytes were invalid. */
910
277k
    if( (b0 | b1 | b2 | b3) != 0xffffffffUL )
911
161k
      {
912
        /* All 16 bytes are valid. */
913
161k
        buf[n + 0] = b0 >> (2 * 8);
914
161k
        buf[n + 1] = b0 >> (1 * 8);
915
161k
        buf[n + 2] = b0 >> (0 * 8);
916
161k
        buf[n + 3] = b1 >> (2 * 8);
917
161k
        buf[n + 4] = b1 >> (1 * 8);
918
161k
        buf[n + 5] = b1 >> (0 * 8);
919
161k
        buf[n + 6] = b2 >> (2 * 8);
920
161k
        buf[n + 7] = b2 >> (1 * 8);
921
161k
        buf[n + 8] = b2 >> (0 * 8);
922
161k
        buf[n + 9] = b3 >> (2 * 8);
923
161k
        buf[n + 10] = b3 >> (1 * 8);
924
161k
        buf[n + 11] = b3 >> (0 * 8);
925
161k
        afx->buffer_pos += 16 - 1;
926
161k
        n += 12;
927
161k
        continue;
928
161k
      }
929
115k
    else if( b0 == 0xffffffffUL )
930
59.3k
      {
931
        /* byte[1..3] have invalid character(s).  Switch to slow
932
           path.  */
933
59.3k
        skip_fast = 1;
934
59.3k
      }
935
56.4k
    else if( b1 == 0xffffffffUL )
936
37.6k
      {
937
        /* byte[4..7] have invalid character(s), first 4 bytes are
938
           valid.  */
939
37.6k
        buf[n + 0] = b0 >> (2 * 8);
940
37.6k
        buf[n + 1] = b0 >> (1 * 8);
941
37.6k
        buf[n + 2] = b0 >> (0 * 8);
942
37.6k
        afx->buffer_pos += 4 - 1;
943
37.6k
        n += 3;
944
37.6k
        skip_fast = 1;
945
37.6k
        continue;
946
37.6k
      }
947
18.7k
    else if( b2 == 0xffffffffUL )
948
11.1k
      {
949
        /* byte[8..11] have invalid character(s), first 8 bytes are
950
           valid.  */
951
11.1k
        buf[n + 0] = b0 >> (2 * 8);
952
11.1k
        buf[n + 1] = b0 >> (1 * 8);
953
11.1k
        buf[n + 2] = b0 >> (0 * 8);
954
11.1k
        buf[n + 3] = b1 >> (2 * 8);
955
11.1k
        buf[n + 4] = b1 >> (1 * 8);
956
11.1k
        buf[n + 5] = b1 >> (0 * 8);
957
11.1k
        afx->buffer_pos += 8 - 1;
958
11.1k
        n += 6;
959
11.1k
        skip_fast = 1;
960
11.1k
        continue;
961
11.1k
      }
962
7.58k
    else /*if( b3 == 0xffffffffUL )*/
963
7.58k
      {
964
        /* byte[12..15] have invalid character(s), first 12 bytes
965
           are valid.  */
966
7.58k
        buf[n + 0] = b0 >> (2 * 8);
967
7.58k
        buf[n + 1] = b0 >> (1 * 8);
968
7.58k
        buf[n + 2] = b0 >> (0 * 8);
969
7.58k
        buf[n + 3] = b1 >> (2 * 8);
970
7.58k
        buf[n + 4] = b1 >> (1 * 8);
971
7.58k
        buf[n + 5] = b1 >> (0 * 8);
972
7.58k
        buf[n + 6] = b2 >> (2 * 8);
973
7.58k
        buf[n + 7] = b2 >> (1 * 8);
974
7.58k
        buf[n + 8] = b2 >> (0 * 8);
975
7.58k
        afx->buffer_pos += 12 - 1;
976
7.58k
        n += 9;
977
7.58k
        skip_fast = 1;
978
7.58k
        continue;
979
7.58k
      }
980
277k
        }
981
982
831k
      switch(idx)
983
831k
        {
984
224k
    case 0: val =  binc << 2; break;
985
208k
    case 1: val |= (binc>>4)&3; buf[n++]=val;val=(binc<<4)&0xf0;break;
986
201k
    case 2: val |= (binc>>2)&15; buf[n++]=val;val=(binc<<6)&0xc0;break;
987
197k
    case 3: val |= binc&0x3f; buf[n++] = val; break;
988
831k
        }
989
831k
      idx = (idx+1) % 4;
990
991
831k
      continue;
992
831k
    }
993
994
1.29M
  skip_fast = 0;
995
996
1.29M
  if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
997
375k
      continue;
998
921k
  else if( c == '=' ) { /* pad character: stop */
999
      /* some mailers leave quoted-printable encoded characters
1000
       * so we try to workaround this */
1001
50.4k
      if( afx->buffer_pos+2 < afx->buffer_len ) {
1002
25.9k
    int cc1, cc2, cc3;
1003
25.9k
    cc1 = afx->buffer[afx->buffer_pos];
1004
25.9k
    cc2 = afx->buffer[afx->buffer_pos+1];
1005
25.9k
    cc3 = afx->buffer[afx->buffer_pos+2];
1006
25.9k
    if( isxdigit(cc1) && isxdigit(cc2)
1007
5.73k
          && strchr( "=\n\r\t ", cc3 )) {
1008
        /* well it seems to be the case - adjust */
1009
5.06k
        c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
1010
5.06k
        c <<= 4;
1011
5.06k
        c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
1012
5.06k
        afx->buffer_pos += 2;
1013
5.06k
        afx->qp_detected = 1;
1014
5.06k
        goto again;
1015
5.06k
    }
1016
25.9k
      }
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
45.4k
            if (afx->buffer_pos + 6 < afx->buffer_len
1024
4.99k
                && afx->buffer[afx->buffer_pos + 0] == '3'
1025
83
                && afx->buffer[afx->buffer_pos + 1] == 'D'
1026
47
                && asctobin[0][afx->buffer[afx->buffer_pos + 2]] != 0xffffffffUL
1027
43
                && asctobin[0][afx->buffer[afx->buffer_pos + 3]] != 0xffffffffUL
1028
39
                && asctobin[0][afx->buffer[afx->buffer_pos + 4]] != 0xffffffffUL
1029
32
                && asctobin[0][afx->buffer[afx->buffer_pos + 5]] != 0xffffffffUL
1030
24
                && 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
45.4k
      if (!n)
1037
29.5k
        onlypad = 1;
1038
1039
45.4k
      if( idx == 1 )
1040
16.4k
    buf[n++] = val;
1041
45.4k
      checkcrc++;
1042
45.4k
      break;
1043
50.4k
  }
1044
870k
        else if (afx->buffer_pos == 1 && c == '-'
1045
24.9k
                 && afx->buffer_len > 9
1046
14.3k
                 && !strncmp (afx->buffer, "-----END ", 9)) {
1047
            /* End in --dearmor mode.  */
1048
25
            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
14
                afx->buffer_pos--;
1053
25
            break;
1054
25
        }
1055
870k
  else {
1056
870k
      log_error(_("invalid radix64 character %02X skipped\n"), c);
1057
870k
      continue;
1058
870k
  }
1059
1.29M
    }
1060
1061
50.1k
    afx->idx = idx;
1062
50.1k
    afx->radbuf[0] = val;
1063
1064
50.1k
    if( n )
1065
30.6k
      {
1066
30.6k
        gcry_md_write (afx->crc_md, buf, n);
1067
30.6k
        afx->any_data = 1;
1068
30.6k
      }
1069
1070
50.1k
    if( checkcrc ) {
1071
45.4k
  gcry_md_final (afx->crc_md);
1072
45.4k
  afx->inp_checked=0;
1073
45.4k
  afx->faked = 0;
1074
106k
  for(;;) { /* skip lf and pad characters */
1075
106k
      if( afx->buffer_pos < afx->buffer_len )
1076
93.4k
    c = afx->buffer[afx->buffer_pos++];
1077
12.8k
      else { /* read the next line */
1078
12.8k
    unsigned maxlen = MAX_LINELEN;
1079
12.8k
    afx->buffer_pos = 0;
1080
12.8k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1081
12.8k
               &afx->buffer_size, &maxlen );
1082
12.8k
    if( !maxlen )
1083
0
        afx->truncated++;
1084
12.8k
    if( !afx->buffer_len )
1085
236
        break; /* eof */
1086
12.6k
    continue;
1087
12.8k
      }
1088
93.4k
      if( c == '\n' || c == ' ' || c == '\r'
1089
71.7k
    || c == '\t' || c == '=' )
1090
48.2k
    continue;
1091
45.1k
      break;
1092
93.4k
  }
1093
45.4k
  if( !afx->buffer_len )
1094
45.4k
      log_error(_("premature eof (no CRC)\n"));
1095
45.1k
  else {
1096
45.1k
      u32 mycrc = 0;
1097
45.1k
      idx = 0;
1098
50.4k
      do {
1099
50.4k
    if( (binc = asctobin[0][c]) == 0xffffffffUL )
1100
43.4k
        break;
1101
7.03k
    switch(idx) {
1102
1.90k
      case 0: val =  binc << 2; break;
1103
1.75k
      case 1: val |= (binc>>4)&3; mycrc |= val << 16;val=(binc<<4)&0xf0;break;
1104
1.71k
      case 2: val |= (binc>>2)&15; mycrc |= val << 8;val=(binc<<6)&0xc0;break;
1105
1.66k
      case 3: val |= binc&0x3f; mycrc |= val; break;
1106
7.03k
    }
1107
7.03k
    for(;;) {
1108
7.03k
        if( afx->buffer_pos < afx->buffer_len )
1109
6.91k
      c = afx->buffer[afx->buffer_pos++];
1110
116
        else { /* read the next line */
1111
116
      unsigned maxlen = MAX_LINELEN;
1112
116
      afx->buffer_pos = 0;
1113
116
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1114
116
                 &afx->buffer_size,
1115
116
                &maxlen );
1116
116
      if( !maxlen )
1117
0
          afx->truncated++;
1118
116
      if( !afx->buffer_len )
1119
116
          break; /* eof */
1120
0
      continue;
1121
116
        }
1122
6.91k
        break;
1123
7.03k
    }
1124
7.03k
    if( !afx->buffer_len )
1125
116
        break; /* eof */
1126
7.03k
      } while( ++idx < 4 );
1127
45.1k
      if( !afx->buffer_len ) {
1128
116
    log_info(_("premature eof (in CRC)\n"));
1129
116
    rc = invalid_crc();
1130
116
      }
1131
45.0k
      else if( idx == 0 ) {
1132
          /* No CRC at all is legal ("MAY") */
1133
43.2k
          rc=0;
1134
43.2k
      }
1135
1.78k
      else if( idx != 4 ) {
1136
125
    log_info(_("malformed CRC\n"));
1137
125
    rc = invalid_crc();
1138
125
      }
1139
1.65k
      else if( mycrc != get_afx_crc (afx) ) {
1140
249
    log_info (_("CRC error; %06lX - %06lX\n"),
1141
249
            (ulong)get_afx_crc (afx), (ulong)mycrc);
1142
249
    rc = invalid_crc();
1143
249
      }
1144
1.41k
      else {
1145
1.41k
    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.41k
      }
1169
45.1k
  }
1170
45.4k
    }
1171
1172
50.1k
    if( !n && !onlypad )
1173
3.25k
  rc = -1;
1174
1175
50.1k
    *retn = n;
1176
50.1k
    return rc;
1177
50.1k
}
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
116k
{
1301
116k
    size_t size = *ret_len;
1302
116k
    armor_filter_context_t *afx = opaque;
1303
116k
    int rc=0, c;
1304
116k
    byte radbuf[3];
1305
116k
    int  idx, idx2;
1306
116k
    size_t n=0;
1307
116k
    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
116k
    if( DBG_FILTER )
1318
116k
  log_debug("armor-filter: control: %d\n", control );
1319
116k
    if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
1320
7.79k
  n = 0;
1321
7.79k
  if( afx->buffer_len ) {
1322
            /* Copy the data from AFX->BUFFER to BUF.  */
1323
508k
            for(; n < size && afx->buffer_pos < afx->buffer_len;)
1324
508k
                buf[n++] = afx->buffer[afx->buffer_pos++];
1325
374
      if( afx->buffer_pos >= afx->buffer_len )
1326
189
    afx->buffer_len = 0;
1327
374
  }
1328
        /* If there is still space in BUF, read directly into it.  */
1329
8.54M
  for(; n < size; n++ ) {
1330
8.54M
      if( (c=iobuf_get(a)) == -1 )
1331
6.67k
    break;
1332
8.53M
      buf[n] = c & 0xff;
1333
8.53M
  }
1334
7.79k
  if( !n )
1335
            /* We didn't get any data.  EOF.  */
1336
5.01k
      rc = -1;
1337
7.79k
  *ret_len = n;
1338
7.79k
    }
1339
108k
    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
84.2k
  if( size < PARTIAL_CHUNK+1 )
1344
0
      BUG(); /* supplied buffer too short */
1345
1346
84.2k
  if( afx->faked )
1347
14.0k
      rc = fake_packet( afx, a, &n, buf, size );
1348
70.1k
  else if( !afx->inp_checked ) {
1349
56.5k
      rc = check_input( afx, a );
1350
56.5k
      if( afx->inp_bypass ) {
1351
2.37M
    for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
1352
2.36M
        buf[n++] = afx->buffer[afx->buffer_pos++];
1353
5.94k
    if( afx->buffer_pos >= afx->buffer_len )
1354
5.74k
        afx->buffer_len = 0;
1355
5.94k
    if( !n )
1356
140
        rc = -1;
1357
5.94k
      }
1358
50.6k
      else if( afx->faked ) {
1359
13.9k
          unsigned int hashes = afx->hashes;
1360
13.9k
                const byte *sesmark;
1361
13.9k
                size_t sesmarklen;
1362
1363
13.9k
                sesmark = get_session_marker( &sesmarklen );
1364
13.9k
                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
13.9k
    hashes &= 1|2|8|16|32|64;
1371
13.9k
    if( !hashes ) {
1372
7.30k
        hashes |= 2;  /* Default to SHA-1. */
1373
7.30k
    }
1374
13.9k
    n=0;
1375
                /* First a gpg control packet... */
1376
13.9k
                buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1377
13.9k
                n++;   /* see below */
1378
13.9k
                memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1379
13.9k
                buf[n++] = CTRLPKT_CLEARSIGN_START;
1380
13.9k
                buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1381
13.9k
                if( hashes & 1 )
1382
2.50k
                    buf[n++] = DIGEST_ALGO_RMD160;
1383
13.9k
                if( hashes & 2 )
1384
12.1k
                    buf[n++] = DIGEST_ALGO_SHA1;
1385
13.9k
                if( hashes & 8 )
1386
1.43k
                    buf[n++] = DIGEST_ALGO_SHA224;
1387
13.9k
                if( hashes & 16 )
1388
733
                    buf[n++] = DIGEST_ALGO_SHA256;
1389
13.9k
                if( hashes & 32 )
1390
923
                    buf[n++] = DIGEST_ALGO_SHA384;
1391
13.9k
                if( hashes & 64 )
1392
1.23k
                    buf[n++] = DIGEST_ALGO_SHA512;
1393
13.9k
                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
13.9k
    buf[n++] = 0xCB; /* new packet format, type 11 */
1401
13.9k
    buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1402
13.9k
    buf[n++] = 't';  /* canonical text mode */
1403
13.9k
    buf[n++] = 0;  /* namelength */
1404
13.9k
    buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1405
13.9k
    memset(buf+n, 0, 4); /* timestamp */
1406
13.9k
    n += 4;
1407
13.9k
      }
1408
36.6k
      else if( !rc )
1409
36.4k
    rc = radix64_read( afx, a, &n, buf, size );
1410
56.5k
  }
1411
13.6k
  else
1412
13.6k
      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
84.2k
  *ret_len = n;
1419
84.2k
    }
1420
24.3k
    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
24.3k
    else if( control == IOBUFCTRL_INIT )
1494
12.1k
      {
1495
12.1k
  if( !is_initialized )
1496
4
    initialize();
1497
1498
  /* Figure out what we're using for line endings if the caller
1499
     didn't specify. */
1500
12.1k
  if(afx->eol[0]==0)
1501
12.1k
    {
1502
#ifdef HAVE_DOSISH_SYSTEM
1503
      afx->eol[0]='\r';
1504
      afx->eol[1]='\n';
1505
#else
1506
12.1k
      afx->eol[0]='\n';
1507
12.1k
#endif
1508
12.1k
    }
1509
12.1k
      }
1510
12.1k
    else if( control == IOBUFCTRL_CANCEL ) {
1511
0
  afx->cancel = 1;
1512
0
    }
1513
12.1k
    else if( control == IOBUFCTRL_FREE ) {
1514
12.1k
  if( afx->cancel )
1515
0
      ;
1516
12.1k
  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
12.1k
  else if( !afx->any_data && !afx->inp_bypass ) {
1570
3.53k
      log_error(_("no valid OpenPGP data found.\n"));
1571
3.53k
      afx->no_openpgp_data = 1;
1572
3.53k
      write_status_text( STATUS_NODATA, "1" );
1573
3.53k
  }
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
12.1k
  if( afx->truncated )
1580
12.1k
      log_info(_("invalid armor: line longer than %d characters\n"),
1581
22
          MAX_LINELEN );
1582
  /* issue an error to enforce dissemination of correct software */
1583
12.1k
  if( afx->qp_detected )
1584
12.1k
      log_error(_("quoted printable character in armor - "
1585
132
      "probably a buggy MTA has been used\n") );
1586
12.1k
  xfree( afx->buffer );
1587
12.1k
  afx->buffer = NULL;
1588
12.1k
        release_armor_context (afx);
1589
12.1k
    }
1590
0
    else if( control == IOBUFCTRL_DESC )
1591
0
        mem2str (buf, "armor_filter", *ret_len);
1592
116k
    return rc;
1593
116k
}
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
}