Coverage Report

Created: 2026-06-07 06:23

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.30M
#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
8.99k
#define BEGIN_SIGNATURE 2
83
24.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.61k
{
116
3.61k
  armor_filter_context_t *afx;
117
3.61k
  gpg_error_t err;
118
119
3.61k
  afx = xcalloc (1, sizeof *afx);
120
3.61k
  if (afx)
121
3.61k
    {
122
3.61k
      err = gcry_md_open (&afx->crc_md, GCRY_MD_CRC24_RFC2440, 0);
123
3.61k
      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.61k
      afx->refcount = 1;
132
3.61k
    }
133
134
3.61k
  return afx;
135
3.61k
}
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
17.1k
{
142
17.1k
  if (!afx)
143
9.97k
    return;
144
17.1k
  log_assert (afx->refcount);
145
7.22k
  if ( --afx->refcount )
146
3.61k
    return;
147
3.61k
  gcry_md_close (afx->crc_md);
148
3.61k
  xfree (afx);
149
3.61k
}
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.61k
{
155
3.61k
  int rc;
156
157
3.61k
  afx->refcount++;
158
3.61k
  rc = iobuf_push_filter (iobuf, armor_filter, afx);
159
3.61k
  if (rc)
160
0
    afx->refcount--;
161
3.61k
  return rc;
162
3.61k
}
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
667
{
200
667
  const byte *crc_buf;
201
667
  u32 crc;
202
203
667
  crc_buf = gcry_md_read (afx->crc_md, GCRY_MD_CRC24_RFC2440);
204
205
667
  crc = crc_buf[0];
206
667
  crc <<= 8;
207
667
  crc |= crc_buf[1];
208
667
  crc <<= 8;
209
667
  crc |= crc_buf[2];
210
211
667
  return crc;
212
667
}
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
37.9k
{
227
37.9k
  int ctb, pkttype;
228
37.9k
  int indeterminate_length_allowed;
229
230
37.9k
    ctb = *buf;
231
37.9k
    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
24.6k
      return 1;
236
237
13.2k
    pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
238
13.2k
    switch( pkttype ) {
239
214
      case PKT_PUBKEY_ENC:
240
3.15k
      case PKT_SIGNATURE:
241
3.31k
      case PKT_SYMKEY_ENC:
242
4.45k
      case PKT_ONEPASS_SIG:
243
4.54k
      case PKT_SECRET_KEY:
244
4.62k
      case PKT_PUBLIC_KEY:
245
5.06k
      case PKT_SECRET_SUBKEY:
246
5.16k
      case PKT_MARKER:
247
5.65k
      case PKT_RING_TRUST:
248
5.87k
      case PKT_USER_ID:
249
5.98k
      case PKT_PUBLIC_SUBKEY:
250
6.24k
      case PKT_ATTRIBUTE:
251
7.12k
      case PKT_MDC:
252
7.12k
  indeterminate_length_allowed = 0;
253
7.12k
        break;
254
255
2.26k
      case PKT_COMPRESSED:
256
2.47k
      case PKT_ENCRYPTED:
257
2.55k
      case PKT_ENCRYPTED_MDC:
258
2.68k
      case PKT_ENCRYPTED_AEAD:
259
3.87k
      case PKT_PLAINTEXT:
260
3.93k
      case PKT_OLD_COMMENT:
261
4.10k
      case PKT_COMMENT:
262
4.23k
      case PKT_GPG_CONTROL:
263
4.23k
  indeterminate_length_allowed = 1;
264
4.23k
        break;
265
266
1.92k
      default:
267
        /* Invalid packet type.  */
268
1.92k
        return 1;
269
13.2k
    }
270
271
11.3k
    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
7.12k
      {
277
7.12k
        int new_format;
278
7.12k
        int indeterminate_length;
279
280
7.12k
        new_format = !! (ctb & (1 << 6));
281
7.12k
        if (new_format)
282
2.86k
          indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
283
4.26k
        else
284
4.26k
          indeterminate_length = (ctb & 3) == 3;
285
286
7.12k
        if (indeterminate_length)
287
1.08k
          return 1;
288
7.12k
      }
289
290
    /* The first CTB seems legit.  It is probably not armored
291
       data.  */
292
10.2k
    return 0;
293
11.3k
}
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
13.5k
{
304
13.5k
    byte buf[2];
305
13.5k
    int n;
306
307
    /* fixme: there might be a problem with iobuf_peek */
308
13.5k
    n = iobuf_peek (a, buf, 2);
309
13.5k
    if( n == -1 )
310
0
  return 0; /* EOF, doesn't matter whether armored or not */
311
13.5k
    if( !n )
312
0
  return 1; /* can't check it: try armored */
313
13.5k
    if (n != 2)
314
30
  return 0; /* short buffer */
315
13.5k
    return is_armored(buf);
316
13.5k
}
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
6.03k
{
339
6.03k
    const char *s, *s2;
340
6.03k
    unsigned found = 0;
341
342
6.03k
    if( strlen(line) < 6  || strlen(line) > 60 )
343
398
  return 0; /* too short or too long */
344
5.63k
    if( memcmp( line, "Hash:", 5 ) )
345
114
  return 0; /* invalid header */
346
347
16.5k
    for(s=line+5;;s=s2) {
348
22.0k
  for(; *s && (*s==' ' || *s == '\t'); s++ )
349
5.55k
      ;
350
16.5k
  if( !*s )
351
3.54k
      break;
352
39.4k
  for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
353
26.4k
      ;
354
12.9k
  if( !strncmp( s, "RIPEMD160", s2-s ) )
355
992
      found |= 1;
356
12.0k
  else if( !strncmp( s, "SHA1", s2-s ) )
357
8.51k
      found |= 2;
358
3.48k
  else if( !strncmp( s, "SHA224", s2-s ) )
359
828
      found |= 8;
360
2.65k
  else if( !strncmp( s, "SHA256", s2-s ) )
361
147
      found |= 16;
362
2.50k
  else if( !strncmp( s, "SHA384", s2-s ) )
363
118
      found |= 32;
364
2.39k
  else if( !strncmp( s, "SHA512", s2-s ) )
365
1.00k
      found |= 64;
366
1.38k
  else
367
1.38k
      return 0;
368
16.8k
  for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
369
5.27k
      ;
370
11.6k
  if( *s2 && *s2 != ',' )
371
588
      return 0;
372
11.0k
  if( *s2 )
373
7.47k
      s2++;
374
11.0k
    }
375
3.54k
    return found;
376
5.52k
}
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
6.03k
{
382
6.03k
  if(strncmp(line,"Version",7)==0
383
5.63k
     || strncmp(line,"Comment",7)==0
384
4.42k
     || strncmp(line,"MessageID",9)==0
385
3.50k
     || strncmp(line,"Hash",4)==0
386
3.18k
     || strncmp(line,"Charset",7)==0)
387
3.43k
    return 1;
388
389
2.60k
  return 0;
390
6.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
1.87M
{
400
1.87M
    const char *s;
401
1.87M
    byte *save_p, *p;
402
1.87M
    int save_c;
403
1.87M
    int i;
404
405
1.87M
    if( len < 15 )
406
1.49M
  return -1; /* too short */
407
378k
    if( memcmp( line, "-----", 5 ) )
408
339k
  return -1; /* no */
409
39.3k
    p = strstr( line+5, "-----");
410
39.3k
    if( !p )
411
4.97k
  return -1;
412
34.3k
    save_p = p;
413
34.3k
    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
34.3k
    if(RFC2440)
424
0
      {
425
0
  if( *p == '\r' )
426
0
    p++;
427
0
  if( *p == '\n' )
428
0
    p++;
429
0
      }
430
34.3k
    else
431
69.4k
      while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
432
35.0k
  p++;
433
434
34.3k
    if( *p )
435
2.02k
  return -1; /* garbage after dashes */
436
32.3k
    save_c = *save_p; *save_p = 0;
437
32.3k
    p = line+5;
438
117k
    for(i=0; (s=head_strings[i]); i++ )
439
110k
  if( !strcmp(s, p) )
440
25.2k
      break;
441
32.3k
    *save_p = save_c;
442
32.3k
    if (!s)
443
7.09k
      {
444
7.09k
        if (!strncmp (p, "BEGIN ", 6))
445
3.46k
          return 42;
446
3.62k
  return -1; /* unknown armor line */
447
7.09k
      }
448
449
25.2k
    if( opt.verbose > 1 )
450
25.2k
  log_info(_("armor: %s\n"), head_strings[i]);
451
25.2k
    return i;
452
32.3k
}
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
42.8k
{
465
42.8k
    byte *p;
466
42.8k
    int hashes=0;
467
42.8k
    unsigned int len2;
468
469
42.8k
    len2 = length_sans_trailing_ws ( line, len );
470
42.8k
    if( !len2 ) {
471
15.4k
        afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
472
15.4k
  return 0; /* WS only: same as empty line */
473
15.4k
    }
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
27.3k
    p = strchr( line, ':');
486
27.3k
    if (!p && afx->dearmor_state)
487
0
      return 0; /* Special treatment in --dearmor mode.  */
488
27.3k
    if( !p || (RFC2440 && p[1]!=' ')
489
14.0k
  || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
490
15.2k
      {
491
15.2k
  log_error (_("invalid armor header: "));
492
15.2k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
493
15.2k
  log_printf ("\n");
494
15.2k
  return -1;
495
15.2k
      }
496
497
    /* Chop off the whitespace we detected before */
498
12.0k
    len=len2;
499
12.0k
    line[len2]='\0';
500
501
12.0k
    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
12.0k
    if (afx->dearmor_mode)
508
0
      ;
509
12.0k
    else if (afx->in_cleartext)
510
6.03k
      {
511
6.03k
  if( (hashes=parse_hash_header( line )) )
512
3.54k
    afx->hashes |= hashes;
513
2.48k
  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.48k
  else
518
2.48k
    {
519
2.48k
      log_error(_("invalid clearsig header\n"));
520
2.48k
      return -1;
521
2.48k
    }
522
6.03k
      }
523
6.03k
    else if(!is_armor_tag(line))
524
2.60k
      {
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.60k
  log_info(_("unknown armor header: "));
533
2.60k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
534
2.60k
  log_printf ("\n");
535
2.60k
      }
536
537
9.58k
    return 1;
538
12.0k
}
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
25.7k
{
546
25.7k
    int rc = 0;
547
25.7k
    int i;
548
25.7k
    byte *line;
549
25.7k
    unsigned len;
550
25.7k
    unsigned maxlen;
551
25.7k
    int hdr_line = -1;
552
553
    /* read the first line to see whether this is armored data */
554
25.7k
    maxlen = MAX_LINELEN;
555
25.7k
    len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
556
25.7k
               &afx->buffer_size, &maxlen );
557
25.7k
    line = afx->buffer;
558
25.7k
    if( !maxlen ) {
559
  /* line has been truncated: assume not armored */
560
21
  afx->inp_checked = 1;
561
21
  afx->inp_bypass = 1;
562
21
  return 0;
563
21
    }
564
565
25.7k
    if( !len ) {
566
41
  return -1; /* eof */
567
41
    }
568
569
    /* (the line is always a C string but maybe longer) */
570
25.6k
    if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
571
1.29k
  ;
572
24.3k
    else if (len >= 2 && !is_armored (line)) {
573
332
  afx->inp_checked = 1;
574
332
  afx->inp_bypass = 1;
575
332
  return 0;
576
332
    }
577
578
    /* find the armor header */
579
1.86M
    while(len) {
580
1.86M
  i = is_armor_header( line, len );
581
1.86M
        if ( i == 42 ) {
582
2.49k
            if (afx->dearmor_mode) {
583
0
                afx->dearmor_state = 1;
584
0
                break;
585
0
            }
586
2.49k
        }
587
1.86M
        else if (i >= 0
588
24.5k
                 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
589
24.5k
      hdr_line = i;
590
24.5k
      if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
591
9.63k
          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
9.63k
    afx->in_cleartext = 1;
596
9.63k
      }
597
24.5k
      break;
598
24.5k
  }
599
600
  /* read the next line (skip all truncated lines) */
601
1.83M
  do {
602
1.83M
      maxlen = MAX_LINELEN;
603
1.83M
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
604
1.83M
                 &afx->buffer_size, &maxlen );
605
1.83M
      line = afx->buffer;
606
1.83M
      len = afx->buffer_len;
607
1.83M
  } while( !maxlen );
608
1.83M
    }
609
610
    /* Parse the header lines.  */
611
34.2k
    while(len) {
612
  /* Read the next line (skip all truncated lines). */
613
33.4k
  do {
614
33.4k
      maxlen = MAX_LINELEN;
615
33.4k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
616
33.4k
                 &afx->buffer_size, &maxlen );
617
33.4k
      line = afx->buffer;
618
33.4k
      len = afx->buffer_len;
619
33.4k
  } while( !maxlen );
620
621
33.4k
  i = parse_header_line( afx, line, len );
622
33.4k
  if( i <= 0 ) {
623
24.5k
      if (i && RFC2440)
624
0
    rc = GPG_ERR_INV_ARMOR;
625
24.5k
      break;
626
24.5k
  }
627
33.4k
    }
628
629
630
25.3k
    if( rc )
631
0
  invalid_armor();
632
25.3k
    else if( afx->in_cleartext )
633
9.63k
  afx->faked = 1;
634
15.6k
    else {
635
15.6k
  afx->inp_checked = 1;
636
15.6k
  gcry_md_reset (afx->crc_md);
637
15.6k
  afx->idx = 0;
638
15.6k
  afx->radbuf[0] = 0;
639
15.6k
    }
640
641
25.3k
    return rc;
642
25.6k
}
643
644
14.7M
#define PARTIAL_CHUNK 512
645
7.71k
#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
9.72k
{
656
9.72k
    int rc = 0;
657
9.72k
    size_t len = 0;
658
9.72k
    int lastline = 0;
659
9.72k
    unsigned maxlen, n;
660
9.72k
    byte *p;
661
9.72k
    byte tempbuf[PARTIAL_CHUNK];
662
9.72k
    size_t tempbuf_len=0;
663
9.72k
    int this_truncated;
664
665
1.18M
    while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
666
  /* copy what we have in the line buffer */
667
1.17M
  if( afx->faked == 1 )
668
9.60k
      afx->faked++; /* skip the first (empty) line */
669
1.16M
  else
670
1.16M
    {
671
      /* It's full, so write this partial chunk */
672
1.16M
      if(tempbuf_len==PARTIAL_CHUNK)
673
7.71k
        {
674
7.71k
    buf[len++]=0xE0+PARTIAL_POW;
675
7.71k
    memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
676
7.71k
    len+=PARTIAL_CHUNK;
677
7.71k
    tempbuf_len=0;
678
7.71k
    continue;
679
7.71k
        }
680
681
5.61M
      while( tempbuf_len < PARTIAL_CHUNK
682
5.60M
       && afx->buffer_pos < afx->buffer_len )
683
4.45M
        tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
684
1.15M
      if( tempbuf_len==PARTIAL_CHUNK )
685
7.71k
        continue;
686
1.15M
    }
687
688
  /* read the next line */
689
1.15M
  maxlen = MAX_LINELEN;
690
1.15M
  afx->buffer_pos = 0;
691
1.15M
  afx->buffer_len = iobuf_read_line( a, &afx->buffer,
692
1.15M
             &afx->buffer_size, &maxlen );
693
1.15M
  if( !afx->buffer_len ) {
694
608
      rc = -1; /* eof (should not happen) */
695
608
      continue;
696
608
  }
697
1.15M
  if( !maxlen )
698
15
          {
699
15
      afx->truncated++;
700
15
            this_truncated = 1;
701
15
          }
702
1.15M
        else
703
1.15M
          this_truncated = 0;
704
705
706
1.15M
  p = afx->buffer;
707
1.15M
  n = afx->buffer_len;
708
709
  /* Armor header or dash-escaped line? */
710
1.15M
  if(p[0]=='-')
711
14.4k
    {
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
14.4k
      if(p[1]==' ' && !afx->not_dash_escaped)
719
62
        {
720
    /* It's a dash-escaped line, so skip over the
721
       escape. */
722
62
    afx->buffer_pos = 2;
723
62
        }
724
14.4k
      else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
725
8.99k
        {
726
    /* Five dashes in a row mean it's probably armor
727
       header. */
728
8.99k
    int type = is_armor_header( p, n );
729
8.99k
                if (type == 42)
730
967
                  type = -1;  /* Only OpenPGP armors are expected.  */
731
8.99k
    if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
732
0
      ; /* this is okay */
733
8.99k
    else
734
8.99k
      {
735
8.99k
        if( type != BEGIN_SIGNATURE )
736
8.75k
          {
737
8.75k
      log_info(_("unexpected armor: "));
738
8.75k
      es_write_sanitized (log_get_stream (), p, n,
739
8.75k
                                            NULL, NULL);
740
8.75k
      log_printf ("\n");
741
8.75k
          }
742
743
8.99k
        lastline = 1;
744
8.99k
        rc = -1;
745
8.99k
      }
746
8.99k
        }
747
5.43k
      else if(!afx->not_dash_escaped)
748
5.43k
        {
749
    /* Bad dash-escaping. */
750
5.43k
    log_info (_("invalid dash escaped line: "));
751
5.43k
    es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
752
5.43k
    log_printf ("\n");
753
5.43k
        }
754
14.4k
    }
755
756
  /* Now handle the end-of-line canonicalization */
757
1.15M
  if( !afx->not_dash_escaped || this_truncated)
758
1.15M
    {
759
1.15M
      int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
760
761
1.15M
      afx->buffer_len=
762
1.15M
        trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
763
1.15M
           " \t\r\n");
764
1.15M
      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.15M
      if( crlf )
783
5.43k
        afx->buffer[afx->buffer_len++] = '\r';
784
1.15M
      afx->buffer[afx->buffer_len++] = this_truncated? '\f':'\n';
785
1.15M
      afx->buffer[afx->buffer_len] = '\0';
786
1.15M
    }
787
1.15M
    }
788
789
9.72k
    if( lastline ) { /* write last (ending) length header */
790
8.99k
        if(tempbuf_len<192)
791
8.06k
    buf[len++]=tempbuf_len;
792
925
  else
793
925
    {
794
925
      buf[len++]=((tempbuf_len-192)/256) + 192;
795
925
      buf[len++]=(tempbuf_len-192) % 256;
796
925
    }
797
8.99k
  memcpy(&buf[len],tempbuf,tempbuf_len);
798
8.99k
  len+=tempbuf_len;
799
800
8.99k
  rc = 0;
801
8.99k
  afx->faked = 0;
802
8.99k
  afx->in_cleartext = 0;
803
  /* and now read the header lines */
804
8.99k
  afx->buffer_pos = 0;
805
9.70k
  for(;;) {
806
9.70k
      int i;
807
808
      /* read the next line (skip all truncated lines) */
809
9.70k
      do {
810
9.70k
    maxlen = MAX_LINELEN;
811
9.70k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
812
9.70k
             &afx->buffer_size, &maxlen );
813
9.70k
      } while( !maxlen );
814
9.70k
      p = afx->buffer;
815
9.70k
      n = afx->buffer_len;
816
9.70k
      if( !n ) {
817
299
    rc = -1;
818
299
    break; /* eof */
819
299
      }
820
9.40k
      i = parse_header_line( afx, p , n );
821
9.40k
      if( i <= 0 ) {
822
8.69k
    if( i )
823
0
        invalid_armor();
824
8.69k
    break;
825
8.69k
      }
826
9.40k
  }
827
8.99k
  afx->inp_checked = 1;
828
8.99k
  gcry_md_reset (afx->crc_md);
829
8.99k
  afx->idx = 0;
830
8.99k
  afx->radbuf[0] = 0;
831
8.99k
    }
832
833
9.72k
    *retn = len;
834
9.72k
    return rc;
835
9.72k
}
836
837
838
static int
839
invalid_crc(void)
840
275
{
841
275
  if ( opt.ignore_crc_error )
842
0
    return 0;
843
275
  log_inc_errorcount();
844
275
  return gpg_error (GPG_ERR_INV_ARMOR);
845
275
}
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
24.8k
{
852
24.8k
    byte val;
853
24.8k
    int c;
854
24.8k
    u32 binc;
855
24.8k
    int checkcrc=0;
856
24.8k
    int rc = 0;
857
24.8k
    size_t n = 0;
858
24.8k
    int idx, onlypad=0;
859
24.8k
    int skip_fast = 0;
860
861
24.8k
    idx = afx->idx;
862
24.8k
    val = afx->radbuf[0];
863
1.97M
    for( n=0; n < size; ) {
864
865
1.97M
  if( afx->buffer_pos < afx->buffer_len )
866
1.74M
      c = afx->buffer[afx->buffer_pos++];
867
228k
  else { /* read the next line */
868
228k
      unsigned maxlen = MAX_LINELEN;
869
228k
      afx->buffer_pos = 0;
870
228k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
871
228k
                 &afx->buffer_size, &maxlen );
872
228k
      if( !maxlen )
873
9
    afx->truncated++;
874
228k
      if( !afx->buffer_len )
875
1.82k
    break; /* eof */
876
226k
      continue;
877
228k
  }
878
879
1.75M
      again:
880
1.75M
  binc = asctobin[0][c];
881
882
1.75M
  if( binc != 0xffffffffUL )
883
731k
    {
884
731k
      if( idx == 0 && skip_fast == 0
885
230k
    && afx->buffer_pos + (16 - 1) < afx->buffer_len
886
137k
    && n + 12 < size)
887
136k
        {
888
    /* Fast path for radix64 to binary conversion.  */
889
136k
    u32 b0,b1,b2,b3;
890
891
    /* Speculatively load 15 more input bytes.  */
892
136k
    b0 = binc << (3 * 6);
893
136k
    b0 |= asctobin[2][afx->buffer[afx->buffer_pos + 0]];
894
136k
    b0 |= asctobin[1][afx->buffer[afx->buffer_pos + 1]];
895
136k
    b0 |= asctobin[0][afx->buffer[afx->buffer_pos + 2]];
896
136k
    b1  = asctobin[3][afx->buffer[afx->buffer_pos + 3]];
897
136k
    b1 |= asctobin[2][afx->buffer[afx->buffer_pos + 4]];
898
136k
    b1 |= asctobin[1][afx->buffer[afx->buffer_pos + 5]];
899
136k
    b1 |= asctobin[0][afx->buffer[afx->buffer_pos + 6]];
900
136k
    b2  = asctobin[3][afx->buffer[afx->buffer_pos + 7]];
901
136k
    b2 |= asctobin[2][afx->buffer[afx->buffer_pos + 8]];
902
136k
    b2 |= asctobin[1][afx->buffer[afx->buffer_pos + 9]];
903
136k
    b2 |= asctobin[0][afx->buffer[afx->buffer_pos + 10]];
904
136k
    b3  = asctobin[3][afx->buffer[afx->buffer_pos + 11]];
905
136k
    b3 |= asctobin[2][afx->buffer[afx->buffer_pos + 12]];
906
136k
    b3 |= asctobin[1][afx->buffer[afx->buffer_pos + 13]];
907
136k
    b3 |= asctobin[0][afx->buffer[afx->buffer_pos + 14]];
908
909
    /* Check if any of the input bytes were invalid. */
910
136k
    if( (b0 | b1 | b2 | b3) != 0xffffffffUL )
911
43.4k
      {
912
        /* All 16 bytes are valid. */
913
43.4k
        buf[n + 0] = b0 >> (2 * 8);
914
43.4k
        buf[n + 1] = b0 >> (1 * 8);
915
43.4k
        buf[n + 2] = b0 >> (0 * 8);
916
43.4k
        buf[n + 3] = b1 >> (2 * 8);
917
43.4k
        buf[n + 4] = b1 >> (1 * 8);
918
43.4k
        buf[n + 5] = b1 >> (0 * 8);
919
43.4k
        buf[n + 6] = b2 >> (2 * 8);
920
43.4k
        buf[n + 7] = b2 >> (1 * 8);
921
43.4k
        buf[n + 8] = b2 >> (0 * 8);
922
43.4k
        buf[n + 9] = b3 >> (2 * 8);
923
43.4k
        buf[n + 10] = b3 >> (1 * 8);
924
43.4k
        buf[n + 11] = b3 >> (0 * 8);
925
43.4k
        afx->buffer_pos += 16 - 1;
926
43.4k
        n += 12;
927
43.4k
        continue;
928
43.4k
      }
929
93.1k
    else if( b0 == 0xffffffffUL )
930
50.6k
      {
931
        /* byte[1..3] have invalid character(s).  Switch to slow
932
           path.  */
933
50.6k
        skip_fast = 1;
934
50.6k
      }
935
42.5k
    else if( b1 == 0xffffffffUL )
936
30.6k
      {
937
        /* byte[4..7] have invalid character(s), first 4 bytes are
938
           valid.  */
939
30.6k
        buf[n + 0] = b0 >> (2 * 8);
940
30.6k
        buf[n + 1] = b0 >> (1 * 8);
941
30.6k
        buf[n + 2] = b0 >> (0 * 8);
942
30.6k
        afx->buffer_pos += 4 - 1;
943
30.6k
        n += 3;
944
30.6k
        skip_fast = 1;
945
30.6k
        continue;
946
30.6k
      }
947
11.9k
    else if( b2 == 0xffffffffUL )
948
7.25k
      {
949
        /* byte[8..11] have invalid character(s), first 8 bytes are
950
           valid.  */
951
7.25k
        buf[n + 0] = b0 >> (2 * 8);
952
7.25k
        buf[n + 1] = b0 >> (1 * 8);
953
7.25k
        buf[n + 2] = b0 >> (0 * 8);
954
7.25k
        buf[n + 3] = b1 >> (2 * 8);
955
7.25k
        buf[n + 4] = b1 >> (1 * 8);
956
7.25k
        buf[n + 5] = b1 >> (0 * 8);
957
7.25k
        afx->buffer_pos += 8 - 1;
958
7.25k
        n += 6;
959
7.25k
        skip_fast = 1;
960
7.25k
        continue;
961
7.25k
      }
962
4.68k
    else /*if( b3 == 0xffffffffUL )*/
963
4.68k
      {
964
        /* byte[12..15] have invalid character(s), first 12 bytes
965
           are valid.  */
966
4.68k
        buf[n + 0] = b0 >> (2 * 8);
967
4.68k
        buf[n + 1] = b0 >> (1 * 8);
968
4.68k
        buf[n + 2] = b0 >> (0 * 8);
969
4.68k
        buf[n + 3] = b1 >> (2 * 8);
970
4.68k
        buf[n + 4] = b1 >> (1 * 8);
971
4.68k
        buf[n + 5] = b1 >> (0 * 8);
972
4.68k
        buf[n + 6] = b2 >> (2 * 8);
973
4.68k
        buf[n + 7] = b2 >> (1 * 8);
974
4.68k
        buf[n + 8] = b2 >> (0 * 8);
975
4.68k
        afx->buffer_pos += 12 - 1;
976
4.68k
        n += 9;
977
4.68k
        skip_fast = 1;
978
4.68k
        continue;
979
4.68k
      }
980
136k
        }
981
982
645k
      switch(idx)
983
645k
        {
984
171k
    case 0: val =  binc << 2; break;
985
160k
    case 1: val |= (binc>>4)&3; buf[n++]=val;val=(binc<<4)&0xf0;break;
986
157k
    case 2: val |= (binc>>2)&15; buf[n++]=val;val=(binc<<6)&0xc0;break;
987
155k
    case 3: val |= binc&0x3f; buf[n++] = val; break;
988
645k
        }
989
645k
      idx = (idx+1) % 4;
990
991
645k
      continue;
992
645k
    }
993
994
1.01M
  skip_fast = 0;
995
996
1.01M
  if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
997
307k
      continue;
998
712k
  else if( c == '=' ) { /* pad character: stop */
999
      /* some mailers leave quoted-printable encoded characters
1000
       * so we try to workaround this */
1001
26.6k
      if( afx->buffer_pos+2 < afx->buffer_len ) {
1002
12.1k
    int cc1, cc2, cc3;
1003
12.1k
    cc1 = afx->buffer[afx->buffer_pos];
1004
12.1k
    cc2 = afx->buffer[afx->buffer_pos+1];
1005
12.1k
    cc3 = afx->buffer[afx->buffer_pos+2];
1006
12.1k
    if( isxdigit(cc1) && isxdigit(cc2)
1007
4.06k
          && strchr( "=\n\r\t ", cc3 )) {
1008
        /* well it seems to be the case - adjust */
1009
3.82k
        c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
1010
3.82k
        c <<= 4;
1011
3.82k
        c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
1012
3.82k
        afx->buffer_pos += 2;
1013
3.82k
        afx->qp_detected = 1;
1014
3.82k
        goto again;
1015
3.82k
    }
1016
12.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
22.7k
            if (afx->buffer_pos + 6 < afx->buffer_len
1024
1.45k
                && afx->buffer[afx->buffer_pos + 0] == '3'
1025
36
                && afx->buffer[afx->buffer_pos + 1] == 'D'
1026
26
                && asctobin[0][afx->buffer[afx->buffer_pos + 2]] != 0xffffffffUL
1027
24
                && asctobin[0][afx->buffer[afx->buffer_pos + 3]] != 0xffffffffUL
1028
22
                && asctobin[0][afx->buffer[afx->buffer_pos + 4]] != 0xffffffffUL
1029
18
                && 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
22.7k
      if (!n)
1037
15.0k
        onlypad = 1;
1038
1039
22.7k
      if( idx == 1 )
1040
10.4k
    buf[n++] = val;
1041
22.7k
      checkcrc++;
1042
22.7k
      break;
1043
26.6k
  }
1044
686k
        else if (afx->buffer_pos == 1 && c == '-'
1045
22.1k
                 && afx->buffer_len > 9
1046
12.7k
                 && !strncmp (afx->buffer, "-----END ", 9)) {
1047
            /* End in --dearmor mode.  */
1048
14
            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
8
                afx->buffer_pos--;
1053
14
            break;
1054
14
        }
1055
686k
  else {
1056
686k
      log_error(_("invalid radix64 character %02X skipped\n"), c);
1057
686k
      continue;
1058
686k
  }
1059
1.01M
    }
1060
1061
24.8k
    afx->idx = idx;
1062
24.8k
    afx->radbuf[0] = val;
1063
1064
24.8k
    if( n )
1065
16.5k
      {
1066
16.5k
        gcry_md_write (afx->crc_md, buf, n);
1067
16.5k
        afx->any_data = 1;
1068
16.5k
      }
1069
1070
24.8k
    if( checkcrc ) {
1071
22.7k
  gcry_md_final (afx->crc_md);
1072
22.7k
  afx->inp_checked=0;
1073
22.7k
  afx->faked = 0;
1074
50.8k
  for(;;) { /* skip lf and pad characters */
1075
50.8k
      if( afx->buffer_pos < afx->buffer_len )
1076
39.7k
    c = afx->buffer[afx->buffer_pos++];
1077
11.0k
      else { /* read the next line */
1078
11.0k
    unsigned maxlen = MAX_LINELEN;
1079
11.0k
    afx->buffer_pos = 0;
1080
11.0k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1081
11.0k
               &afx->buffer_size, &maxlen );
1082
11.0k
    if( !maxlen )
1083
0
        afx->truncated++;
1084
11.0k
    if( !afx->buffer_len )
1085
99
        break; /* eof */
1086
10.9k
    continue;
1087
11.0k
      }
1088
39.7k
      if( c == '\n' || c == ' ' || c == '\r'
1089
28.1k
    || c == '\t' || c == '=' )
1090
17.0k
    continue;
1091
22.6k
      break;
1092
39.7k
  }
1093
22.7k
  if( !afx->buffer_len )
1094
22.7k
      log_error(_("premature eof (no CRC)\n"));
1095
22.6k
  else {
1096
22.6k
      u32 mycrc = 0;
1097
22.6k
      idx = 0;
1098
24.4k
      do {
1099
24.4k
    if( (binc = asctobin[0][c]) == 0xffffffffUL )
1100
22.0k
        break;
1101
2.43k
    switch(idx) {
1102
702
      case 0: val =  binc << 2; break;
1103
607
      case 1: val |= (binc>>4)&3; mycrc |= val << 16;val=(binc<<4)&0xf0;break;
1104
579
      case 2: val |= (binc>>2)&15; mycrc |= val << 8;val=(binc<<6)&0xc0;break;
1105
547
      case 3: val |= binc&0x3f; mycrc |= val; break;
1106
2.43k
    }
1107
2.43k
    for(;;) {
1108
2.43k
        if( afx->buffer_pos < afx->buffer_len )
1109
2.34k
      c = afx->buffer[afx->buffer_pos++];
1110
86
        else { /* read the next line */
1111
86
      unsigned maxlen = MAX_LINELEN;
1112
86
      afx->buffer_pos = 0;
1113
86
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1114
86
                 &afx->buffer_size,
1115
86
                &maxlen );
1116
86
      if( !maxlen )
1117
0
          afx->truncated++;
1118
86
      if( !afx->buffer_len )
1119
86
          break; /* eof */
1120
0
      continue;
1121
86
        }
1122
2.34k
        break;
1123
2.43k
    }
1124
2.43k
    if( !afx->buffer_len )
1125
86
        break; /* eof */
1126
2.43k
      } while( ++idx < 4 );
1127
22.6k
      if( !afx->buffer_len ) {
1128
86
    log_info(_("premature eof (in CRC)\n"));
1129
86
    rc = invalid_crc();
1130
86
      }
1131
22.5k
      else if( idx == 0 ) {
1132
          /* No CRC at all is legal ("MAY") */
1133
21.9k
          rc=0;
1134
21.9k
      }
1135
616
      else if( idx != 4 ) {
1136
69
    log_info(_("malformed CRC\n"));
1137
69
    rc = invalid_crc();
1138
69
      }
1139
547
      else if( mycrc != get_afx_crc (afx) ) {
1140
120
    log_info (_("CRC error; %06lX - %06lX\n"),
1141
120
            (ulong)get_afx_crc (afx), (ulong)mycrc);
1142
120
    rc = invalid_crc();
1143
120
      }
1144
427
      else {
1145
427
    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
427
      }
1169
22.6k
  }
1170
22.7k
    }
1171
1172
24.8k
    if( !n && !onlypad )
1173
1.40k
  rc = -1;
1174
1175
24.8k
    *retn = n;
1176
24.8k
    return rc;
1177
24.8k
}
1178
1179
static void
1180
armor_output_buf_as_radix64 (armor_filter_context_t *afx, IOBUF a,
1181
           byte *buf, size_t size)
1182
0
{
1183
0
  byte radbuf[sizeof (afx->radbuf)];
1184
0
  byte outbuf[64 + sizeof (afx->eol)];
1185
0
  unsigned int eollen = strlen (afx->eol);
1186
0
  u32 in, in2;
1187
0
  int idx, idx2;
1188
0
  int i;
1189
1190
0
  idx = afx->idx;
1191
0
  idx2 = afx->idx2;
1192
0
  memcpy (radbuf, afx->radbuf, sizeof (afx->radbuf));
1193
1194
0
  if (size && (idx || idx2))
1195
0
    {
1196
      /* preload eol to outbuf buffer */
1197
0
      memcpy (outbuf + 4, afx->eol, sizeof (afx->eol));
1198
1199
0
      for (; size && (idx || idx2); buf++, size--)
1200
0
  {
1201
0
    radbuf[idx++] = *buf;
1202
0
    if (idx > 2)
1203
0
      {
1204
0
        idx = 0;
1205
0
        in = (u32)radbuf[0] << (2 * 8);
1206
0
        in |= (u32)radbuf[1] << (1 * 8);
1207
0
        in |= (u32)radbuf[2] << (0 * 8);
1208
0
        outbuf[0] = bintoasc[(in >> 18) & 077];
1209
0
        outbuf[1] = bintoasc[(in >> 12) & 077];
1210
0
        outbuf[2] = bintoasc[(in >> 6) & 077];
1211
0
        outbuf[3] = bintoasc[(in >> 0) & 077];
1212
0
        if (++idx2 >= (64/4))
1213
0
    { /* pgp doesn't like 72 here */
1214
0
      idx2=0;
1215
0
      iobuf_write (a, outbuf, 4 + eollen);
1216
0
    }
1217
0
        else
1218
0
    {
1219
0
      iobuf_write (a, outbuf, 4);
1220
0
    }
1221
0
      }
1222
0
  }
1223
0
    }
1224
1225
0
  if (size >= (64/4)*3)
1226
0
    {
1227
      /* preload eol to outbuf buffer */
1228
0
      memcpy (outbuf + 64, afx->eol, sizeof(afx->eol));
1229
1230
0
      do
1231
0
  {
1232
    /* idx and idx2 == 0 */
1233
1234
0
    for (i = 0; i < (64/8); i++)
1235
0
      {
1236
0
        in = (u32)buf[0] << (2 * 8);
1237
0
        in |= (u32)buf[1] << (1 * 8);
1238
0
        in |= (u32)buf[2] << (0 * 8);
1239
0
        in2 = (u32)buf[3] << (2 * 8);
1240
0
        in2 |= (u32)buf[4] << (1 * 8);
1241
0
        in2 |= (u32)buf[5] << (0 * 8);
1242
0
        outbuf[i*8+0] = bintoasc[(in >> 18) & 077];
1243
0
        outbuf[i*8+1] = bintoasc[(in >> 12) & 077];
1244
0
        outbuf[i*8+2] = bintoasc[(in >> 6) & 077];
1245
0
        outbuf[i*8+3] = bintoasc[(in >> 0) & 077];
1246
0
        outbuf[i*8+4] = bintoasc[(in2 >> 18) & 077];
1247
0
        outbuf[i*8+5] = bintoasc[(in2 >> 12) & 077];
1248
0
        outbuf[i*8+6] = bintoasc[(in2 >> 6) & 077];
1249
0
        outbuf[i*8+7] = bintoasc[(in2 >> 0) & 077];
1250
0
        buf+=6;
1251
0
        size-=6;
1252
0
      }
1253
1254
    /* pgp doesn't like 72 here */
1255
0
    iobuf_write (a, outbuf, 64 + eollen);
1256
0
  }
1257
0
      while (size >= (64/4)*3);
1258
1259
      /* restore eol for tail handling */
1260
0
      if (size)
1261
0
  memcpy (outbuf + 4, afx->eol, sizeof (afx->eol));
1262
0
    }
1263
1264
0
  for (; size; buf++, size--)
1265
0
    {
1266
0
      radbuf[idx++] = *buf;
1267
0
      if (idx > 2)
1268
0
  {
1269
0
    idx = 0;
1270
0
    in = (u32)radbuf[0] << (2 * 8);
1271
0
    in |= (u32)radbuf[1] << (1 * 8);
1272
0
    in |= (u32)radbuf[2] << (0 * 8);
1273
0
    outbuf[0] = bintoasc[(in >> 18) & 077];
1274
0
    outbuf[1] = bintoasc[(in >> 12) & 077];
1275
0
    outbuf[2] = bintoasc[(in >> 6) & 077];
1276
0
    outbuf[3] = bintoasc[(in >> 0) & 077];
1277
0
    if (++idx2 >= (64/4))
1278
0
      { /* pgp doesn't like 72 here */
1279
0
        idx2=0;
1280
0
        iobuf_write (a, outbuf, 4 + eollen);
1281
0
      }
1282
0
    else
1283
0
      {
1284
0
        iobuf_write (a, outbuf, 4);
1285
0
      }
1286
0
  }
1287
0
    }
1288
1289
0
  memcpy (afx->radbuf, radbuf, sizeof (afx->radbuf));
1290
0
  afx->idx = idx;
1291
0
  afx->idx2 = idx2;
1292
0
}
1293
1294
/****************
1295
 * This filter is used to handle the armor stuff
1296
 */
1297
static int
1298
armor_filter( void *opaque, int control,
1299
       IOBUF a, byte *buf, size_t *ret_len)
1300
53.3k
{
1301
53.3k
    size_t size = *ret_len;
1302
53.3k
    armor_filter_context_t *afx = opaque;
1303
53.3k
    int rc=0, c;
1304
53.3k
    byte radbuf[3];
1305
53.3k
    int  idx, idx2;
1306
53.3k
    size_t n=0;
1307
53.3k
    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
53.3k
    if( DBG_FILTER )
1318
53.3k
  log_debug("armor-filter: control: %d\n", control );
1319
53.3k
    if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
1320
1.47k
  n = 0;
1321
1.47k
  if( afx->buffer_len ) {
1322
            /* Copy the data from AFX->BUFFER to BUF.  */
1323
405k
            for(; n < size && afx->buffer_pos < afx->buffer_len;)
1324
405k
                buf[n++] = afx->buffer[afx->buffer_pos++];
1325
269
      if( afx->buffer_pos >= afx->buffer_len )
1326
123
    afx->buffer_len = 0;
1327
269
  }
1328
        /* If there is still space in BUF, read directly into it.  */
1329
6.89M
  for(; n < size; n++ ) {
1330
6.89M
      if( (c=iobuf_get(a)) == -1 )
1331
446
    break;
1332
6.89M
      buf[n] = c & 0xff;
1333
6.89M
  }
1334
1.47k
  if( !n )
1335
            /* We didn't get any data.  EOF.  */
1336
243
      rc = -1;
1337
1.47k
  *ret_len = n;
1338
1.47k
    }
1339
51.8k
    else if( control == IOBUFCTRL_UNDERFLOW ) {
1340
        /* We need some space for the faked packet.  The minimum
1341
         * required size is the PARTIAL_CHUNK size plus a byte for the
1342
         * length itself */
1343
44.6k
  if( size < PARTIAL_CHUNK+1 )
1344
0
      BUG(); /* supplied buffer too short */
1345
1346
44.6k
  if( afx->faked )
1347
9.72k
      rc = fake_packet( afx, a, &n, buf, size );
1348
34.9k
  else if( !afx->inp_checked ) {
1349
25.7k
      rc = check_input( afx, a );
1350
25.7k
      if( afx->inp_bypass ) {
1351
679k
    for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
1352
679k
        buf[n++] = afx->buffer[afx->buffer_pos++];
1353
353
    if( afx->buffer_pos >= afx->buffer_len )
1354
222
        afx->buffer_len = 0;
1355
353
    if( !n )
1356
50
        rc = -1;
1357
353
      }
1358
25.3k
      else if( afx->faked ) {
1359
9.63k
          unsigned int hashes = afx->hashes;
1360
9.63k
                const byte *sesmark;
1361
9.63k
                size_t sesmarklen;
1362
1363
9.63k
                sesmark = get_session_marker( &sesmarklen );
1364
9.63k
                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
9.63k
    hashes &= 1|2|8|16|32|64;
1371
9.63k
    if( !hashes ) {
1372
5.51k
        hashes |= 2;  /* Default to SHA-1. */
1373
5.51k
    }
1374
9.63k
    n=0;
1375
                /* First a gpg control packet... */
1376
9.63k
                buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1377
9.63k
                n++;   /* see below */
1378
9.63k
                memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1379
9.63k
                buf[n++] = CTRLPKT_CLEARSIGN_START;
1380
9.63k
                buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1381
9.63k
                if( hashes & 1 )
1382
2.49k
                    buf[n++] = DIGEST_ALGO_RMD160;
1383
9.63k
                if( hashes & 2 )
1384
8.93k
                    buf[n++] = DIGEST_ALGO_SHA1;
1385
9.63k
                if( hashes & 8 )
1386
594
                    buf[n++] = DIGEST_ALGO_SHA224;
1387
9.63k
                if( hashes & 16 )
1388
441
                    buf[n++] = DIGEST_ALGO_SHA256;
1389
9.63k
                if( hashes & 32 )
1390
115
                    buf[n++] = DIGEST_ALGO_SHA384;
1391
9.63k
                if( hashes & 64 )
1392
548
                    buf[n++] = DIGEST_ALGO_SHA512;
1393
9.63k
                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
9.63k
    buf[n++] = 0xCB; /* new packet format, type 11 */
1401
9.63k
    buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1402
9.63k
    buf[n++] = 't';  /* canonical text mode */
1403
9.63k
    buf[n++] = 0;  /* namelength */
1404
9.63k
    buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1405
9.63k
    memset(buf+n, 0, 4); /* timestamp */
1406
9.63k
    n += 4;
1407
9.63k
      }
1408
15.7k
      else if( !rc )
1409
15.6k
    rc = radix64_read( afx, a, &n, buf, size );
1410
25.7k
  }
1411
9.18k
  else
1412
9.18k
      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
44.6k
  *ret_len = n;
1419
44.6k
    }
1420
7.22k
    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
7.22k
    else if( control == IOBUFCTRL_INIT )
1494
3.61k
      {
1495
3.61k
  if( !is_initialized )
1496
1
    initialize();
1497
1498
  /* Figure out what we're using for line endings if the caller
1499
     didn't specify. */
1500
3.61k
  if(afx->eol[0]==0)
1501
3.61k
    {
1502
#ifdef HAVE_DOSISH_SYSTEM
1503
      afx->eol[0]='\r';
1504
      afx->eol[1]='\n';
1505
#else
1506
3.61k
      afx->eol[0]='\n';
1507
3.61k
#endif
1508
3.61k
    }
1509
3.61k
      }
1510
3.61k
    else if( control == IOBUFCTRL_CANCEL ) {
1511
0
  afx->cancel = 1;
1512
0
    }
1513
3.61k
    else if( control == IOBUFCTRL_FREE ) {
1514
3.61k
  if( afx->cancel )
1515
0
      ;
1516
3.61k
  else if( afx->status ) { /* pad, write checksum, and bottom line */
1517
0
      gcry_md_final (afx->crc_md);
1518
0
      crc = get_afx_crc (afx);
1519
0
      idx = afx->idx;
1520
0
      idx2 = afx->idx2;
1521
0
      if( idx ) {
1522
0
    c = bintoasc[(afx->radbuf[0]>>2)&077];
1523
0
    iobuf_put(a, c);
1524
0
    if( idx == 1 ) {
1525
0
        c = bintoasc[((afx->radbuf[0] << 4) & 060) & 077];
1526
0
        iobuf_put(a, c);
1527
0
        iobuf_put(a, '=');
1528
0
        iobuf_put(a, '=');
1529
0
    }
1530
0
    else { /* 2 */
1531
0
        c = bintoasc[(((afx->radbuf[0]<<4)&060)
1532
0
                                  |((afx->radbuf[1]>>4)&017))&077];
1533
0
        iobuf_put(a, c);
1534
0
        c = bintoasc[((afx->radbuf[1] << 2) & 074) & 077];
1535
0
        iobuf_put(a, c);
1536
0
        iobuf_put(a, '=');
1537
0
    }
1538
0
    if( ++idx2 >= (64/4) )
1539
0
      { /* pgp doesn't like 72 here */
1540
0
        iobuf_writestr(a,afx->eol);
1541
0
        idx2=0;
1542
0
      }
1543
0
      }
1544
      /* may need a linefeed */
1545
0
      if( idx2 )
1546
0
        iobuf_writestr(a,afx->eol);
1547
      /* write the CRC */
1548
0
      iobuf_put(a, '=');
1549
0
      radbuf[0] = crc >>16;
1550
0
      radbuf[1] = crc >> 8;
1551
0
      radbuf[2] = crc;
1552
0
      c = bintoasc[(*radbuf >> 2) & 077];
1553
0
      iobuf_put(a, c);
1554
0
      c = bintoasc[(((*radbuf<<4)&060)|((radbuf[1] >> 4)&017))&077];
1555
0
      iobuf_put(a, c);
1556
0
      c = bintoasc[(((radbuf[1]<<2)&074)|((radbuf[2]>>6)&03))&077];
1557
0
      iobuf_put(a, c);
1558
0
      c = bintoasc[radbuf[2]&077];
1559
0
      iobuf_put(a, c);
1560
0
      iobuf_writestr(a,afx->eol);
1561
      /* and the trailer */
1562
0
      if( afx->what >= DIM(tail_strings) )
1563
0
    log_bug("afx->what=%d", afx->what);
1564
0
      iobuf_writestr(a, "-----");
1565
0
      iobuf_writestr(a, tail_strings[afx->what] );
1566
0
      iobuf_writestr(a, "-----" );
1567
0
      iobuf_writestr(a,afx->eol);
1568
0
  }
1569
3.61k
  else if( !afx->any_data && !afx->inp_bypass ) {
1570
2.00k
      log_error(_("no valid OpenPGP data found.\n"));
1571
2.00k
      afx->no_openpgp_data = 1;
1572
2.00k
      write_status_text( STATUS_NODATA, "1" );
1573
2.00k
  }
1574
        /* Note that in a cleartext signature truncated lines in the
1575
         * plaintext are detected and propagated to the signature
1576
         * checking code by inserting a \f into the plaintext.  We do
1577
         * not use log_info here because some of the truncated lines
1578
         * are harmless.  */
1579
3.61k
  if( afx->truncated )
1580
3.61k
      log_info(_("invalid armor: line longer than %d characters\n"),
1581
18
          MAX_LINELEN );
1582
  /* issue an error to enforce dissemination of correct software */
1583
3.61k
  if( afx->qp_detected )
1584
3.61k
      log_error(_("quoted printable character in armor - "
1585
65
      "probably a buggy MTA has been used\n") );
1586
3.61k
  xfree( afx->buffer );
1587
3.61k
  afx->buffer = NULL;
1588
3.61k
        release_armor_context (afx);
1589
3.61k
    }
1590
0
    else if( control == IOBUFCTRL_DESC )
1591
0
        mem2str (buf, "armor_filter", *ret_len);
1592
53.3k
    return rc;
1593
53.3k
}
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
}