Coverage Report

Created: 2026-06-09 06:38

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
5.04M
#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
9.49k
#define BEGIN_SIGNATURE 2
83
22.3k
#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.16k
{
116
3.16k
  armor_filter_context_t *afx;
117
3.16k
  gpg_error_t err;
118
119
3.16k
  afx = xcalloc (1, sizeof *afx);
120
3.16k
  if (afx)
121
3.16k
    {
122
3.16k
      err = gcry_md_open (&afx->crc_md, GCRY_MD_CRC24_RFC2440, 0);
123
3.16k
      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.16k
      afx->refcount = 1;
132
3.16k
    }
133
134
3.16k
  return afx;
135
3.16k
}
136
137
/* Release an armor filter context.  Passing NULL is explicitly
138
   allowed and a no-op.  */
139
void
140
release_armor_context (armor_filter_context_t *afx)
141
15.2k
{
142
15.2k
  if (!afx)
143
8.93k
    return;
144
15.2k
  log_assert (afx->refcount);
145
6.33k
  if ( --afx->refcount )
146
3.16k
    return;
147
3.16k
  gcry_md_close (afx->crc_md);
148
3.16k
  xfree (afx);
149
3.16k
}
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.16k
{
155
3.16k
  int rc;
156
157
3.16k
  afx->refcount++;
158
3.16k
  rc = iobuf_push_filter (iobuf, armor_filter, afx);
159
3.16k
  if (rc)
160
0
    afx->refcount--;
161
3.16k
  return rc;
162
3.16k
}
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
560
{
200
560
  const byte *crc_buf;
201
560
  u32 crc;
202
203
560
  crc_buf = gcry_md_read (afx->crc_md, GCRY_MD_CRC24_RFC2440);
204
205
560
  crc = crc_buf[0];
206
560
  crc <<= 8;
207
560
  crc |= crc_buf[1];
208
560
  crc <<= 8;
209
560
  crc |= crc_buf[2];
210
211
560
  return crc;
212
560
}
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
34.4k
{
227
34.4k
  int ctb, pkttype;
228
34.4k
  int indeterminate_length_allowed;
229
230
34.4k
    ctb = *buf;
231
34.4k
    if( !(ctb & 0x80) )
232
      /* The most significant bit of the CTB must be set.  Since it is
233
         cleared, this is not a binary OpenPGP message.  Assume it is
234
         armored.  */
235
22.3k
      return 1;
236
237
12.0k
    pkttype =  ctb & 0x40 ? (ctb & 0x3f) : ((ctb>>2)&0xf);
238
12.0k
    switch( pkttype ) {
239
196
      case PKT_PUBKEY_ENC:
240
2.89k
      case PKT_SIGNATURE:
241
3.03k
      case PKT_SYMKEY_ENC:
242
4.09k
      case PKT_ONEPASS_SIG:
243
4.17k
      case PKT_SECRET_KEY:
244
4.24k
      case PKT_PUBLIC_KEY:
245
4.63k
      case PKT_SECRET_SUBKEY:
246
4.73k
      case PKT_MARKER:
247
5.14k
      case PKT_RING_TRUST:
248
5.34k
      case PKT_USER_ID:
249
5.45k
      case PKT_PUBLIC_SUBKEY:
250
5.69k
      case PKT_ATTRIBUTE:
251
6.45k
      case PKT_MDC:
252
6.45k
  indeterminate_length_allowed = 0;
253
6.45k
        break;
254
255
2.02k
      case PKT_COMPRESSED:
256
2.19k
      case PKT_ENCRYPTED:
257
2.26k
      case PKT_ENCRYPTED_MDC:
258
2.39k
      case PKT_ENCRYPTED_AEAD:
259
3.41k
      case PKT_PLAINTEXT:
260
3.46k
      case PKT_OLD_COMMENT:
261
3.63k
      case PKT_COMMENT:
262
3.72k
      case PKT_GPG_CONTROL:
263
3.72k
  indeterminate_length_allowed = 1;
264
3.72k
        break;
265
266
1.85k
      default:
267
        /* Invalid packet type.  */
268
1.85k
        return 1;
269
12.0k
    }
270
271
10.1k
    if (! indeterminate_length_allowed)
272
      /* It is only legal to use an indeterminate length with a few
273
         packet types.  If a packet uses an indeterminate length, but
274
         that is not allowed, then the data is not valid binary
275
         OpenPGP data.  */
276
6.45k
      {
277
6.45k
        int new_format;
278
6.45k
        int indeterminate_length;
279
280
6.45k
        new_format = !! (ctb & (1 << 6));
281
6.45k
        if (new_format)
282
2.58k
          indeterminate_length = (buf[1] >= 224 && buf[1] < 255);
283
3.87k
        else
284
3.87k
          indeterminate_length = (ctb & 3) == 3;
285
286
6.45k
        if (indeterminate_length)
287
984
          return 1;
288
6.45k
      }
289
290
    /* The first CTB seems legit.  It is probably not armored
291
       data.  */
292
9.20k
    return 0;
293
10.1k
}
294
295
296
/****************
297
 * Try to check whether the iobuf is armored
298
 * Returns true if this may be the case; the caller should use the
299
 *     filter to do further processing.
300
 */
301
int
302
use_armor_filter( IOBUF a )
303
12.1k
{
304
12.1k
    byte buf[2];
305
12.1k
    int n;
306
307
    /* fixme: there might be a problem with iobuf_peek */
308
12.1k
    n = iobuf_peek (a, buf, 2);
309
12.1k
    if( n == -1 )
310
0
  return 0; /* EOF, doesn't matter whether armored or not */
311
12.1k
    if( !n )
312
0
  return 1; /* can't check it: try armored */
313
12.1k
    if (n != 2)
314
26
  return 0; /* short buffer */
315
12.0k
    return is_armored(buf);
316
12.1k
}
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
5.61k
{
339
5.61k
    const char *s, *s2;
340
5.61k
    unsigned found = 0;
341
342
5.61k
    if( strlen(line) < 6  || strlen(line) > 60 )
343
349
  return 0; /* too short or too long */
344
5.26k
    if( memcmp( line, "Hash:", 5 ) )
345
95
  return 0; /* invalid header */
346
347
15.9k
    for(s=line+5;;s=s2) {
348
21.1k
  for(; *s && (*s==' ' || *s == '\t'); s++ )
349
5.19k
      ;
350
15.9k
  if( !*s )
351
3.45k
      break;
352
37.0k
  for(s2=s+1; *s2 && *s2!=' ' && *s2 != '\t' && *s2 != ','; s2++ )
353
24.5k
      ;
354
12.5k
  if( !strncmp( s, "RIPEMD160", s2-s ) )
355
986
      found |= 1;
356
11.5k
  else if( !strncmp( s, "SHA1", s2-s ) )
357
8.27k
      found |= 2;
358
3.26k
  else if( !strncmp( s, "SHA224", s2-s ) )
359
756
      found |= 8;
360
2.50k
  else if( !strncmp( s, "SHA256", s2-s ) )
361
151
      found |= 16;
362
2.35k
  else if( !strncmp( s, "SHA384", s2-s ) )
363
173
      found |= 32;
364
2.18k
  else if( !strncmp( s, "SHA512", s2-s ) )
365
1.05k
      found |= 64;
366
1.12k
  else
367
1.12k
      return 0;
368
16.5k
  for(; *s2 && (*s2==' ' || *s2 == '\t'); s2++ )
369
5.19k
      ;
370
11.3k
  if( *s2 && *s2 != ',' )
371
582
      return 0;
372
10.8k
  if( *s2 )
373
7.36k
      s2++;
374
10.8k
    }
375
3.45k
    return found;
376
5.16k
}
377
378
/* Returns true if this is a valid armor tag as per RFC-2440bis-21. */
379
static int
380
is_armor_tag(const char *line)
381
5.44k
{
382
5.44k
  if(strncmp(line,"Version",7)==0
383
5.18k
     || strncmp(line,"Comment",7)==0
384
3.96k
     || strncmp(line,"MessageID",9)==0
385
3.13k
     || strncmp(line,"Hash",4)==0
386
2.83k
     || strncmp(line,"Charset",7)==0)
387
3.13k
    return 1;
388
389
2.30k
  return 0;
390
5.44k
}
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
3.88M
{
400
3.88M
    const char *s;
401
3.88M
    byte *save_p, *p;
402
3.88M
    int save_c;
403
3.88M
    int i;
404
405
3.88M
    if( len < 15 )
406
3.57M
  return -1; /* too short */
407
315k
    if( memcmp( line, "-----", 5 ) )
408
279k
  return -1; /* no */
409
36.0k
    p = strstr( line+5, "-----");
410
36.0k
    if( !p )
411
4.48k
  return -1;
412
31.5k
    save_p = p;
413
31.5k
    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
31.5k
    if(RFC2440)
424
0
      {
425
0
  if( *p == '\r' )
426
0
    p++;
427
0
  if( *p == '\n' )
428
0
    p++;
429
0
      }
430
31.5k
    else
431
62.9k
      while(*p==' ' || *p=='\r' || *p=='\n' || *p=='\t')
432
31.4k
  p++;
433
434
31.5k
    if( *p )
435
2.41k
  return -1; /* garbage after dashes */
436
29.1k
    save_c = *save_p; *save_p = 0;
437
29.1k
    p = line+5;
438
109k
    for(i=0; (s=head_strings[i]); i++ )
439
102k
  if( !strcmp(s, p) )
440
22.8k
      break;
441
29.1k
    *save_p = save_c;
442
29.1k
    if (!s)
443
6.27k
      {
444
6.27k
        if (!strncmp (p, "BEGIN ", 6))
445
2.84k
          return 42;
446
3.43k
  return -1; /* unknown armor line */
447
6.27k
      }
448
449
22.8k
    if( opt.verbose > 1 )
450
22.8k
  log_info(_("armor: %s\n"), head_strings[i]);
451
22.8k
    return i;
452
29.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
40.5k
{
465
40.5k
    byte *p;
466
40.5k
    int hashes=0;
467
40.5k
    unsigned int len2;
468
469
40.5k
    len2 = length_sans_trailing_ws ( line, len );
470
40.5k
    if( !len2 ) {
471
16.9k
        afx->buffer_pos = len2;  /* (it is not the fine way to do it here) */
472
16.9k
  return 0; /* WS only: same as empty line */
473
16.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
23.5k
    p = strchr( line, ':');
486
23.5k
    if (!p && afx->dearmor_state)
487
0
      return 0; /* Special treatment in --dearmor mode.  */
488
23.5k
    if( !p || (RFC2440 && p[1]!=' ')
489
13.0k
  || (!RFC2440 && p[1]!=' ' && p[1]!='\n' && p[1]!='\r'))
490
12.5k
      {
491
12.5k
  log_error (_("invalid armor header: "));
492
12.5k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
493
12.5k
  log_printf ("\n");
494
12.5k
  return -1;
495
12.5k
      }
496
497
    /* Chop off the whitespace we detected before */
498
11.0k
    len=len2;
499
11.0k
    line[len2]='\0';
500
501
11.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
11.0k
    if (afx->dearmor_mode)
508
0
      ;
509
11.0k
    else if (afx->in_cleartext)
510
5.61k
      {
511
5.61k
  if( (hashes=parse_hash_header( line )) )
512
3.45k
    afx->hashes |= hashes;
513
2.15k
  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.15k
  else
518
2.15k
    {
519
2.15k
      log_error(_("invalid clearsig header\n"));
520
2.15k
      return -1;
521
2.15k
    }
522
5.61k
      }
523
5.44k
    else if(!is_armor_tag(line))
524
2.30k
      {
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.30k
  log_info(_("unknown armor header: "));
533
2.30k
  es_write_sanitized (log_get_stream (), line, len, NULL, NULL);
534
2.30k
  log_printf ("\n");
535
2.30k
      }
536
537
8.89k
    return 1;
538
11.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
23.4k
{
546
23.4k
    int rc = 0;
547
23.4k
    int i;
548
23.4k
    byte *line;
549
23.4k
    unsigned len;
550
23.4k
    unsigned maxlen;
551
23.4k
    int hdr_line = -1;
552
553
    /* read the first line to see whether this is armored data */
554
23.4k
    maxlen = MAX_LINELEN;
555
23.4k
    len = afx->buffer_len = iobuf_read_line( a, &afx->buffer,
556
23.4k
               &afx->buffer_size, &maxlen );
557
23.4k
    line = afx->buffer;
558
23.4k
    if( !maxlen ) {
559
  /* line has been truncated: assume not armored */
560
18
  afx->inp_checked = 1;
561
18
  afx->inp_bypass = 1;
562
18
  return 0;
563
18
    }
564
565
23.4k
    if( !len ) {
566
38
  return -1; /* eof */
567
38
    }
568
569
    /* (the line is always a C string but maybe longer) */
570
23.3k
    if( *line == '\n' || ( len && (*line == '\r' && line[1]=='\n') ) )
571
1.02k
  ;
572
22.3k
    else if (len >= 2 && !is_armored (line)) {
573
292
  afx->inp_checked = 1;
574
292
  afx->inp_bypass = 1;
575
292
  return 0;
576
292
    }
577
578
    /* find the armor header */
579
3.87M
    while(len) {
580
3.87M
  i = is_armor_header( line, len );
581
3.87M
        if ( i == 42 ) {
582
2.13k
            if (afx->dearmor_mode) {
583
0
                afx->dearmor_state = 1;
584
0
                break;
585
0
            }
586
2.13k
        }
587
3.87M
        else if (i >= 0
588
22.3k
                 && !(afx->only_keyblocks && i != 1 && i != 5 && i != 6 )) {
589
22.3k
      hdr_line = i;
590
22.3k
      if( hdr_line == BEGIN_SIGNED_MSG_IDX ) {
591
10.0k
          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
10.0k
    afx->in_cleartext = 1;
596
10.0k
      }
597
22.3k
      break;
598
22.3k
  }
599
600
  /* read the next line (skip all truncated lines) */
601
3.85M
  do {
602
3.85M
      maxlen = MAX_LINELEN;
603
3.85M
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
604
3.85M
                 &afx->buffer_size, &maxlen );
605
3.85M
      line = afx->buffer;
606
3.85M
      len = afx->buffer_len;
607
3.85M
  } while( !maxlen );
608
3.85M
    }
609
610
    /* Parse the header lines.  */
611
31.5k
    while(len) {
612
  /* Read the next line (skip all truncated lines). */
613
30.8k
  do {
614
30.8k
      maxlen = MAX_LINELEN;
615
30.8k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
616
30.8k
                 &afx->buffer_size, &maxlen );
617
30.8k
      line = afx->buffer;
618
30.8k
      len = afx->buffer_len;
619
30.8k
  } while( !maxlen );
620
621
30.8k
  i = parse_header_line( afx, line, len );
622
30.8k
  if( i <= 0 ) {
623
22.3k
      if (i && RFC2440)
624
0
    rc = GPG_ERR_INV_ARMOR;
625
22.3k
      break;
626
22.3k
  }
627
30.8k
    }
628
629
630
23.0k
    if( rc )
631
0
  invalid_armor();
632
23.0k
    else if( afx->in_cleartext )
633
10.0k
  afx->faked = 1;
634
13.0k
    else {
635
13.0k
  afx->inp_checked = 1;
636
13.0k
  gcry_md_reset (afx->crc_md);
637
13.0k
  afx->idx = 0;
638
13.0k
  afx->radbuf[0] = 0;
639
13.0k
    }
640
641
23.0k
    return rc;
642
23.3k
}
643
644
11.8M
#define PARTIAL_CHUNK 512
645
6.30k
#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
10.1k
{
656
10.1k
    int rc = 0;
657
10.1k
    size_t len = 0;
658
10.1k
    int lastline = 0;
659
10.1k
    unsigned maxlen, n;
660
10.1k
    byte *p;
661
10.1k
    byte tempbuf[PARTIAL_CHUNK];
662
10.1k
    size_t tempbuf_len=0;
663
10.1k
    int this_truncated;
664
665
912k
    while( !rc && size-len>=(PARTIAL_CHUNK+1)) {
666
  /* copy what we have in the line buffer */
667
902k
  if( afx->faked == 1 )
668
10.0k
      afx->faked++; /* skip the first (empty) line */
669
891k
  else
670
891k
    {
671
      /* It's full, so write this partial chunk */
672
891k
      if(tempbuf_len==PARTIAL_CHUNK)
673
6.30k
        {
674
6.30k
    buf[len++]=0xE0+PARTIAL_POW;
675
6.30k
    memcpy(&buf[len],tempbuf,PARTIAL_CHUNK);
676
6.30k
    len+=PARTIAL_CHUNK;
677
6.30k
    tempbuf_len=0;
678
6.30k
    continue;
679
6.30k
        }
680
681
4.57M
      while( tempbuf_len < PARTIAL_CHUNK
682
4.56M
       && afx->buffer_pos < afx->buffer_len )
683
3.68M
        tempbuf[tempbuf_len++] = afx->buffer[afx->buffer_pos++];
684
885k
      if( tempbuf_len==PARTIAL_CHUNK )
685
6.30k
        continue;
686
885k
    }
687
688
  /* read the next line */
689
889k
  maxlen = MAX_LINELEN;
690
889k
  afx->buffer_pos = 0;
691
889k
  afx->buffer_len = iobuf_read_line( a, &afx->buffer,
692
889k
             &afx->buffer_size, &maxlen );
693
889k
  if( !afx->buffer_len ) {
694
542
      rc = -1; /* eof (should not happen) */
695
542
      continue;
696
542
  }
697
888k
  if( !maxlen )
698
13
          {
699
13
      afx->truncated++;
700
13
            this_truncated = 1;
701
13
          }
702
888k
        else
703
888k
          this_truncated = 0;
704
705
706
888k
  p = afx->buffer;
707
888k
  n = afx->buffer_len;
708
709
  /* Armor header or dash-escaped line? */
710
888k
  if(p[0]=='-')
711
13.8k
    {
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
13.8k
      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
13.8k
      else if(p[1]=='-' && p[2]=='-' && p[3]=='-' && p[4]=='-')
725
9.49k
        {
726
    /* Five dashes in a row mean it's probably armor
727
       header. */
728
9.49k
    int type = is_armor_header( p, n );
729
9.49k
                if (type == 42)
730
705
                  type = -1;  /* Only OpenPGP armors are expected.  */
731
9.49k
    if( afx->not_dash_escaped && type != BEGIN_SIGNATURE )
732
0
      ; /* this is okay */
733
9.49k
    else
734
9.49k
      {
735
9.49k
        if( type != BEGIN_SIGNATURE )
736
9.37k
          {
737
9.37k
      log_info(_("unexpected armor: "));
738
9.37k
      es_write_sanitized (log_get_stream (), p, n,
739
9.37k
                                            NULL, NULL);
740
9.37k
      log_printf ("\n");
741
9.37k
          }
742
743
9.49k
        lastline = 1;
744
9.49k
        rc = -1;
745
9.49k
      }
746
9.49k
        }
747
4.30k
      else if(!afx->not_dash_escaped)
748
4.30k
        {
749
    /* Bad dash-escaping. */
750
4.30k
    log_info (_("invalid dash escaped line: "));
751
4.30k
    es_write_sanitized (log_get_stream (), p, n, NULL, NULL);
752
4.30k
    log_printf ("\n");
753
4.30k
        }
754
13.8k
    }
755
756
  /* Now handle the end-of-line canonicalization */
757
888k
  if( !afx->not_dash_escaped || this_truncated)
758
888k
    {
759
888k
      int crlf = n > 1 && p[n-2] == '\r' && p[n-1]=='\n';
760
761
888k
      afx->buffer_len=
762
888k
        trim_trailing_chars( &p[afx->buffer_pos], n-afx->buffer_pos,
763
888k
           " \t\r\n");
764
888k
      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
888k
      if( crlf )
783
4.17k
        afx->buffer[afx->buffer_len++] = '\r';
784
888k
      afx->buffer[afx->buffer_len++] = this_truncated? '\f':'\n';
785
888k
      afx->buffer[afx->buffer_len] = '\0';
786
888k
    }
787
888k
    }
788
789
10.1k
    if( lastline ) { /* write last (ending) length header */
790
9.49k
        if(tempbuf_len<192)
791
8.60k
    buf[len++]=tempbuf_len;
792
890
  else
793
890
    {
794
890
      buf[len++]=((tempbuf_len-192)/256) + 192;
795
890
      buf[len++]=(tempbuf_len-192) % 256;
796
890
    }
797
9.49k
  memcpy(&buf[len],tempbuf,tempbuf_len);
798
9.49k
  len+=tempbuf_len;
799
800
9.49k
  rc = 0;
801
9.49k
  afx->faked = 0;
802
9.49k
  afx->in_cleartext = 0;
803
  /* and now read the header lines */
804
9.49k
  afx->buffer_pos = 0;
805
9.93k
  for(;;) {
806
9.93k
      int i;
807
808
      /* read the next line (skip all truncated lines) */
809
9.93k
      do {
810
9.93k
    maxlen = MAX_LINELEN;
811
9.93k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
812
9.93k
             &afx->buffer_size, &maxlen );
813
9.93k
      } while( !maxlen );
814
9.93k
      p = afx->buffer;
815
9.93k
      n = afx->buffer_len;
816
9.93k
      if( !n ) {
817
255
    rc = -1;
818
255
    break; /* eof */
819
255
      }
820
9.67k
      i = parse_header_line( afx, p , n );
821
9.67k
      if( i <= 0 ) {
822
9.24k
    if( i )
823
0
        invalid_armor();
824
9.24k
    break;
825
9.24k
      }
826
9.67k
  }
827
9.49k
  afx->inp_checked = 1;
828
9.49k
  gcry_md_reset (afx->crc_md);
829
9.49k
  afx->idx = 0;
830
9.49k
  afx->radbuf[0] = 0;
831
9.49k
    }
832
833
10.1k
    *retn = len;
834
10.1k
    return rc;
835
10.1k
}
836
837
838
static int
839
invalid_crc(void)
840
232
{
841
232
  if ( opt.ignore_crc_error )
842
0
    return 0;
843
232
  log_inc_errorcount();
844
232
  return gpg_error (GPG_ERR_INV_ARMOR);
845
232
}
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
22.7k
{
852
22.7k
    byte val;
853
22.7k
    int c;
854
22.7k
    u32 binc;
855
22.7k
    int checkcrc=0;
856
22.7k
    int rc = 0;
857
22.7k
    size_t n = 0;
858
22.7k
    int idx, onlypad=0;
859
22.7k
    int skip_fast = 0;
860
861
22.7k
    idx = afx->idx;
862
22.7k
    val = afx->radbuf[0];
863
1.91M
    for( n=0; n < size; ) {
864
865
1.91M
  if( afx->buffer_pos < afx->buffer_len )
866
1.68M
      c = afx->buffer[afx->buffer_pos++];
867
227k
  else { /* read the next line */
868
227k
      unsigned maxlen = MAX_LINELEN;
869
227k
      afx->buffer_pos = 0;
870
227k
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
871
227k
                 &afx->buffer_size, &maxlen );
872
227k
      if( !maxlen )
873
7
    afx->truncated++;
874
227k
      if( !afx->buffer_len )
875
1.59k
    break; /* eof */
876
225k
      continue;
877
227k
  }
878
879
1.68M
      again:
880
1.68M
  binc = asctobin[0][c];
881
882
1.68M
  if( binc != 0xffffffffUL )
883
717k
    {
884
717k
      if( idx == 0 && skip_fast == 0
885
225k
    && afx->buffer_pos + (16 - 1) < afx->buffer_len
886
134k
    && n + 12 < size)
887
134k
        {
888
    /* Fast path for radix64 to binary conversion.  */
889
134k
    u32 b0,b1,b2,b3;
890
891
    /* Speculatively load 15 more input bytes.  */
892
134k
    b0 = binc << (3 * 6);
893
134k
    b0 |= asctobin[2][afx->buffer[afx->buffer_pos + 0]];
894
134k
    b0 |= asctobin[1][afx->buffer[afx->buffer_pos + 1]];
895
134k
    b0 |= asctobin[0][afx->buffer[afx->buffer_pos + 2]];
896
134k
    b1  = asctobin[3][afx->buffer[afx->buffer_pos + 3]];
897
134k
    b1 |= asctobin[2][afx->buffer[afx->buffer_pos + 4]];
898
134k
    b1 |= asctobin[1][afx->buffer[afx->buffer_pos + 5]];
899
134k
    b1 |= asctobin[0][afx->buffer[afx->buffer_pos + 6]];
900
134k
    b2  = asctobin[3][afx->buffer[afx->buffer_pos + 7]];
901
134k
    b2 |= asctobin[2][afx->buffer[afx->buffer_pos + 8]];
902
134k
    b2 |= asctobin[1][afx->buffer[afx->buffer_pos + 9]];
903
134k
    b2 |= asctobin[0][afx->buffer[afx->buffer_pos + 10]];
904
134k
    b3  = asctobin[3][afx->buffer[afx->buffer_pos + 11]];
905
134k
    b3 |= asctobin[2][afx->buffer[afx->buffer_pos + 12]];
906
134k
    b3 |= asctobin[1][afx->buffer[afx->buffer_pos + 13]];
907
134k
    b3 |= asctobin[0][afx->buffer[afx->buffer_pos + 14]];
908
909
    /* Check if any of the input bytes were invalid. */
910
134k
    if( (b0 | b1 | b2 | b3) != 0xffffffffUL )
911
44.0k
      {
912
        /* All 16 bytes are valid. */
913
44.0k
        buf[n + 0] = b0 >> (2 * 8);
914
44.0k
        buf[n + 1] = b0 >> (1 * 8);
915
44.0k
        buf[n + 2] = b0 >> (0 * 8);
916
44.0k
        buf[n + 3] = b1 >> (2 * 8);
917
44.0k
        buf[n + 4] = b1 >> (1 * 8);
918
44.0k
        buf[n + 5] = b1 >> (0 * 8);
919
44.0k
        buf[n + 6] = b2 >> (2 * 8);
920
44.0k
        buf[n + 7] = b2 >> (1 * 8);
921
44.0k
        buf[n + 8] = b2 >> (0 * 8);
922
44.0k
        buf[n + 9] = b3 >> (2 * 8);
923
44.0k
        buf[n + 10] = b3 >> (1 * 8);
924
44.0k
        buf[n + 11] = b3 >> (0 * 8);
925
44.0k
        afx->buffer_pos += 16 - 1;
926
44.0k
        n += 12;
927
44.0k
        continue;
928
44.0k
      }
929
90.1k
    else if( b0 == 0xffffffffUL )
930
49.2k
      {
931
        /* byte[1..3] have invalid character(s).  Switch to slow
932
           path.  */
933
49.2k
        skip_fast = 1;
934
49.2k
      }
935
40.9k
    else if( b1 == 0xffffffffUL )
936
28.3k
      {
937
        /* byte[4..7] have invalid character(s), first 4 bytes are
938
           valid.  */
939
28.3k
        buf[n + 0] = b0 >> (2 * 8);
940
28.3k
        buf[n + 1] = b0 >> (1 * 8);
941
28.3k
        buf[n + 2] = b0 >> (0 * 8);
942
28.3k
        afx->buffer_pos += 4 - 1;
943
28.3k
        n += 3;
944
28.3k
        skip_fast = 1;
945
28.3k
        continue;
946
28.3k
      }
947
12.6k
    else if( b2 == 0xffffffffUL )
948
7.16k
      {
949
        /* byte[8..11] have invalid character(s), first 8 bytes are
950
           valid.  */
951
7.16k
        buf[n + 0] = b0 >> (2 * 8);
952
7.16k
        buf[n + 1] = b0 >> (1 * 8);
953
7.16k
        buf[n + 2] = b0 >> (0 * 8);
954
7.16k
        buf[n + 3] = b1 >> (2 * 8);
955
7.16k
        buf[n + 4] = b1 >> (1 * 8);
956
7.16k
        buf[n + 5] = b1 >> (0 * 8);
957
7.16k
        afx->buffer_pos += 8 - 1;
958
7.16k
        n += 6;
959
7.16k
        skip_fast = 1;
960
7.16k
        continue;
961
7.16k
      }
962
5.47k
    else /*if( b3 == 0xffffffffUL )*/
963
5.47k
      {
964
        /* byte[12..15] have invalid character(s), first 12 bytes
965
           are valid.  */
966
5.47k
        buf[n + 0] = b0 >> (2 * 8);
967
5.47k
        buf[n + 1] = b0 >> (1 * 8);
968
5.47k
        buf[n + 2] = b0 >> (0 * 8);
969
5.47k
        buf[n + 3] = b1 >> (2 * 8);
970
5.47k
        buf[n + 4] = b1 >> (1 * 8);
971
5.47k
        buf[n + 5] = b1 >> (0 * 8);
972
5.47k
        buf[n + 6] = b2 >> (2 * 8);
973
5.47k
        buf[n + 7] = b2 >> (1 * 8);
974
5.47k
        buf[n + 8] = b2 >> (0 * 8);
975
5.47k
        afx->buffer_pos += 12 - 1;
976
5.47k
        n += 9;
977
5.47k
        skip_fast = 1;
978
5.47k
        continue;
979
5.47k
      }
980
134k
        }
981
982
632k
      switch(idx)
983
632k
        {
984
166k
    case 0: val =  binc << 2; break;
985
157k
    case 1: val |= (binc>>4)&3; buf[n++]=val;val=(binc<<4)&0xf0;break;
986
155k
    case 2: val |= (binc>>2)&15; buf[n++]=val;val=(binc<<6)&0xc0;break;
987
153k
    case 3: val |= binc&0x3f; buf[n++] = val; break;
988
632k
        }
989
632k
      idx = (idx+1) % 4;
990
991
632k
      continue;
992
632k
    }
993
994
968k
  skip_fast = 0;
995
996
968k
  if( c == '\n' || c == ' ' || c == '\r' || c == '\t' )
997
297k
      continue;
998
670k
  else if( c == '=' ) { /* pad character: stop */
999
      /* some mailers leave quoted-printable encoded characters
1000
       * so we try to workaround this */
1001
23.7k
      if( afx->buffer_pos+2 < afx->buffer_len ) {
1002
12.2k
    int cc1, cc2, cc3;
1003
12.2k
    cc1 = afx->buffer[afx->buffer_pos];
1004
12.2k
    cc2 = afx->buffer[afx->buffer_pos+1];
1005
12.2k
    cc3 = afx->buffer[afx->buffer_pos+2];
1006
12.2k
    if( isxdigit(cc1) && isxdigit(cc2)
1007
3.13k
          && strchr( "=\n\r\t ", cc3 )) {
1008
        /* well it seems to be the case - adjust */
1009
2.94k
        c = isdigit(cc1)? (cc1 - '0'): (ascii_toupper(cc1)-'A'+10);
1010
2.94k
        c <<= 4;
1011
2.94k
        c |= isdigit(cc2)? (cc2 - '0'): (ascii_toupper(cc2)-'A'+10);
1012
2.94k
        afx->buffer_pos += 2;
1013
2.94k
        afx->qp_detected = 1;
1014
2.94k
        goto again;
1015
2.94k
    }
1016
12.2k
      }
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
20.8k
            if (afx->buffer_pos + 6 < afx->buffer_len
1024
1.55k
                && 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
20.8k
      if (!n)
1037
13.8k
        onlypad = 1;
1038
1039
20.8k
      if( idx == 1 )
1040
8.14k
    buf[n++] = val;
1041
20.8k
      checkcrc++;
1042
20.8k
      break;
1043
23.7k
  }
1044
646k
        else if (afx->buffer_pos == 1 && c == '-'
1045
21.0k
                 && 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
646k
  else {
1056
646k
      log_error(_("invalid radix64 character %02X skipped\n"), c);
1057
646k
      continue;
1058
646k
  }
1059
968k
    }
1060
1061
22.7k
    afx->idx = idx;
1062
22.7k
    afx->radbuf[0] = val;
1063
1064
22.7k
    if( n )
1065
13.7k
      {
1066
13.7k
        gcry_md_write (afx->crc_md, buf, n);
1067
13.7k
        afx->any_data = 1;
1068
13.7k
      }
1069
1070
22.7k
    if( checkcrc ) {
1071
20.8k
  gcry_md_final (afx->crc_md);
1072
20.8k
  afx->inp_checked=0;
1073
20.8k
  afx->faked = 0;
1074
43.6k
  for(;;) { /* skip lf and pad characters */
1075
43.6k
      if( afx->buffer_pos < afx->buffer_len )
1076
35.1k
    c = afx->buffer[afx->buffer_pos++];
1077
8.52k
      else { /* read the next line */
1078
8.52k
    unsigned maxlen = MAX_LINELEN;
1079
8.52k
    afx->buffer_pos = 0;
1080
8.52k
    afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1081
8.52k
               &afx->buffer_size, &maxlen );
1082
8.52k
    if( !maxlen )
1083
0
        afx->truncated++;
1084
8.52k
    if( !afx->buffer_len )
1085
95
        break; /* eof */
1086
8.43k
    continue;
1087
8.52k
      }
1088
35.1k
      if( c == '\n' || c == ' ' || c == '\r'
1089
26.2k
    || c == '\t' || c == '=' )
1090
14.3k
    continue;
1091
20.7k
      break;
1092
35.1k
  }
1093
20.8k
  if( !afx->buffer_len )
1094
20.8k
      log_error(_("premature eof (no CRC)\n"));
1095
20.7k
  else {
1096
20.7k
      u32 mycrc = 0;
1097
20.7k
      idx = 0;
1098
22.2k
      do {
1099
22.2k
    if( (binc = asctobin[0][c]) == 0xffffffffUL )
1100
20.2k
        break;
1101
1.99k
    switch(idx) {
1102
574
      case 0: val =  binc << 2; break;
1103
499
      case 1: val |= (binc>>4)&3; mycrc |= val << 16;val=(binc<<4)&0xf0;break;
1104
474
      case 2: val |= (binc>>2)&15; mycrc |= val << 8;val=(binc<<6)&0xc0;break;
1105
451
      case 3: val |= binc&0x3f; mycrc |= val; break;
1106
1.99k
    }
1107
1.99k
    for(;;) {
1108
1.99k
        if( afx->buffer_pos < afx->buffer_len )
1109
1.92k
      c = afx->buffer[afx->buffer_pos++];
1110
76
        else { /* read the next line */
1111
76
      unsigned maxlen = MAX_LINELEN;
1112
76
      afx->buffer_pos = 0;
1113
76
      afx->buffer_len = iobuf_read_line( a, &afx->buffer,
1114
76
                 &afx->buffer_size,
1115
76
                &maxlen );
1116
76
      if( !maxlen )
1117
0
          afx->truncated++;
1118
76
      if( !afx->buffer_len )
1119
76
          break; /* eof */
1120
0
      continue;
1121
76
        }
1122
1.92k
        break;
1123
1.99k
    }
1124
1.99k
    if( !afx->buffer_len )
1125
76
        break; /* eof */
1126
1.99k
      } while( ++idx < 4 );
1127
20.7k
      if( !afx->buffer_len ) {
1128
76
    log_info(_("premature eof (in CRC)\n"));
1129
76
    rc = invalid_crc();
1130
76
      }
1131
20.6k
      else if( idx == 0 ) {
1132
          /* No CRC at all is legal ("MAY") */
1133
20.1k
          rc=0;
1134
20.1k
      }
1135
498
      else if( idx != 4 ) {
1136
47
    log_info(_("malformed CRC\n"));
1137
47
    rc = invalid_crc();
1138
47
      }
1139
451
      else if( mycrc != get_afx_crc (afx) ) {
1140
109
    log_info (_("CRC error; %06lX - %06lX\n"),
1141
109
            (ulong)get_afx_crc (afx), (ulong)mycrc);
1142
109
    rc = invalid_crc();
1143
109
      }
1144
342
      else {
1145
342
    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
342
      }
1169
20.7k
  }
1170
20.8k
    }
1171
1172
22.7k
    if( !n && !onlypad )
1173
1.22k
  rc = -1;
1174
1175
22.7k
    *retn = n;
1176
22.7k
    return rc;
1177
22.7k
}
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
51.0k
{
1301
51.0k
    size_t size = *ret_len;
1302
51.0k
    armor_filter_context_t *afx = opaque;
1303
51.0k
    int rc=0, c;
1304
51.0k
    byte radbuf[3];
1305
51.0k
    int  idx, idx2;
1306
51.0k
    size_t n=0;
1307
51.0k
    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
51.0k
    if( DBG_FILTER )
1318
51.0k
  log_debug("armor-filter: control: %d\n", control );
1319
51.0k
    if( control == IOBUFCTRL_UNDERFLOW && afx->inp_bypass ) {
1320
1.42k
  n = 0;
1321
1.42k
  if( afx->buffer_len ) {
1322
            /* Copy the data from AFX->BUFFER to BUF.  */
1323
483k
            for(; n < size && afx->buffer_pos < afx->buffer_len;)
1324
483k
                buf[n++] = afx->buffer[afx->buffer_pos++];
1325
261
      if( afx->buffer_pos >= afx->buffer_len )
1326
116
    afx->buffer_len = 0;
1327
261
  }
1328
        /* If there is still space in BUF, read directly into it.  */
1329
7.40M
  for(; n < size; n++ ) {
1330
7.39M
      if( (c=iobuf_get(a)) == -1 )
1331
396
    break;
1332
7.39M
      buf[n] = c & 0xff;
1333
7.39M
  }
1334
1.42k
  if( !n )
1335
            /* We didn't get any data.  EOF.  */
1336
220
      rc = -1;
1337
1.42k
  *ret_len = n;
1338
1.42k
    }
1339
49.6k
    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
43.3k
  if( size < PARTIAL_CHUNK+1 )
1344
0
      BUG(); /* supplied buffer too short */
1345
1346
43.3k
  if( afx->faked )
1347
10.1k
      rc = fake_packet( afx, a, &n, buf, size );
1348
33.1k
  else if( !afx->inp_checked ) {
1349
23.4k
      rc = check_input( afx, a );
1350
23.4k
      if( afx->inp_bypass ) {
1351
524k
    for(n=0; n < size && afx->buffer_pos < afx->buffer_len; )
1352
523k
        buf[n++] = afx->buffer[afx->buffer_pos++];
1353
310
    if( afx->buffer_pos >= afx->buffer_len )
1354
186
        afx->buffer_len = 0;
1355
310
    if( !n )
1356
42
        rc = -1;
1357
310
      }
1358
23.1k
      else if( afx->faked ) {
1359
10.0k
          unsigned int hashes = afx->hashes;
1360
10.0k
                const byte *sesmark;
1361
10.0k
                size_t sesmarklen;
1362
1363
10.0k
                sesmark = get_session_marker( &sesmarklen );
1364
10.0k
                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
10.0k
    hashes &= 1|2|8|16|32|64;
1371
10.0k
    if( !hashes ) {
1372
6.99k
        hashes |= 2;  /* Default to SHA-1. */
1373
6.99k
    }
1374
10.0k
    n=0;
1375
                /* First a gpg control packet... */
1376
10.0k
                buf[n++] = 0xff; /* new format, type 63, 1 length byte */
1377
10.0k
                n++;   /* see below */
1378
10.0k
                memcpy(buf+n, sesmark, sesmarklen ); n+= sesmarklen;
1379
10.0k
                buf[n++] = CTRLPKT_CLEARSIGN_START;
1380
10.0k
                buf[n++] = afx->not_dash_escaped? 0:1; /* sigclass */
1381
10.0k
                if( hashes & 1 )
1382
1.73k
                    buf[n++] = DIGEST_ALGO_RMD160;
1383
10.0k
                if( hashes & 2 )
1384
9.36k
                    buf[n++] = DIGEST_ALGO_SHA1;
1385
10.0k
                if( hashes & 8 )
1386
587
                    buf[n++] = DIGEST_ALGO_SHA224;
1387
10.0k
                if( hashes & 16 )
1388
444
                    buf[n++] = DIGEST_ALGO_SHA256;
1389
10.0k
                if( hashes & 32 )
1390
180
                    buf[n++] = DIGEST_ALGO_SHA384;
1391
10.0k
                if( hashes & 64 )
1392
607
                    buf[n++] = DIGEST_ALGO_SHA512;
1393
10.0k
                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
10.0k
    buf[n++] = 0xCB; /* new packet format, type 11 */
1401
10.0k
    buf[n++] = 0xE1; /* 2^1 == 2 bytes */
1402
10.0k
    buf[n++] = 't';  /* canonical text mode */
1403
10.0k
    buf[n++] = 0;  /* namelength */
1404
10.0k
    buf[n++] = 0xE2; /* 2^2 == 4 more bytes */
1405
10.0k
    memset(buf+n, 0, 4); /* timestamp */
1406
10.0k
    n += 4;
1407
10.0k
      }
1408
13.0k
      else if( !rc )
1409
13.0k
    rc = radix64_read( afx, a, &n, buf, size );
1410
23.4k
  }
1411
9.75k
  else
1412
9.75k
      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
43.3k
  *ret_len = n;
1419
43.3k
    }
1420
6.33k
    else if( control == IOBUFCTRL_FLUSH && !afx->cancel ) {
1421
0
  if( !afx->status ) { /* write the header line */
1422
0
      const char *s;
1423
0
      strlist_t comment=opt.comments;
1424
1425
0
      if( afx->what >= DIM(head_strings) )
1426
0
    log_bug("afx->what=%d", afx->what);
1427
0
      iobuf_writestr(a, "-----");
1428
0
      iobuf_writestr(a, head_strings[afx->what] );
1429
0
      iobuf_writestr(a, "-----" );
1430
0
      iobuf_writestr(a,afx->eol);
1431
0
      if (opt.emit_version)
1432
0
        {
1433
0
    iobuf_writestr (a, "Version: "GNUPG_NAME" v");
1434
0
                for (s=VERSION; *s && *s != '.'; s++)
1435
0
                  iobuf_writebyte (a, *s);
1436
0
                if (opt.emit_version > 1 && *s)
1437
0
                  {
1438
0
                    iobuf_writebyte (a, *s++);
1439
0
                    for (; *s && *s != '.'; s++)
1440
0
                      iobuf_writebyte (a, *s);
1441
0
                    if (opt.emit_version > 2)
1442
0
                      {
1443
0
                        for (; *s && *s != '-' && !spacep (s); s++)
1444
0
                          iobuf_writebyte (a, *s);
1445
0
                        if (opt.emit_version > 3)
1446
0
                          iobuf_writestr (a, " (" PRINTABLE_OS_NAME ")");
1447
0
                      }
1448
0
                  }
1449
0
    iobuf_writestr(a,afx->eol);
1450
0
        }
1451
1452
      /* write the comment strings */
1453
0
      for(;comment;comment=comment->next)
1454
0
        {
1455
0
    iobuf_writestr(a, "Comment: " );
1456
0
    for( s=comment->d; *s; s++ )
1457
0
      {
1458
0
        if( *s == '\n' )
1459
0
          iobuf_writestr(a, "\\n" );
1460
0
        else if( *s == '\r' )
1461
0
          iobuf_writestr(a, "\\r" );
1462
0
        else if( *s == '\v' )
1463
0
          iobuf_writestr(a, "\\v" );
1464
0
        else
1465
0
          iobuf_put(a, *s );
1466
0
      }
1467
1468
0
    iobuf_writestr(a,afx->eol);
1469
0
        }
1470
1471
0
      if ( afx->hdrlines ) {
1472
0
                for ( s = afx->hdrlines; *s; s++ ) {
1473
#ifdef HAVE_DOSISH_SYSTEM
1474
                    if ( *s == '\n' )
1475
                        iobuf_put( a, '\r');
1476
#endif
1477
0
                    iobuf_put(a, *s );
1478
0
                }
1479
0
            }
1480
1481
0
      iobuf_writestr(a,afx->eol);
1482
0
      afx->status++;
1483
0
      afx->idx = 0;
1484
0
      afx->idx2 = 0;
1485
0
      gcry_md_reset (afx->crc_md);
1486
0
  }
1487
1488
0
  if( size ) {
1489
0
      gcry_md_write (afx->crc_md, buf, size);
1490
0
      armor_output_buf_as_radix64 (afx, a, buf, size);
1491
0
        }
1492
0
    }
1493
6.33k
    else if( control == IOBUFCTRL_INIT )
1494
3.16k
      {
1495
3.16k
  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.16k
  if(afx->eol[0]==0)
1501
3.16k
    {
1502
#ifdef HAVE_DOSISH_SYSTEM
1503
      afx->eol[0]='\r';
1504
      afx->eol[1]='\n';
1505
#else
1506
3.16k
      afx->eol[0]='\n';
1507
3.16k
#endif
1508
3.16k
    }
1509
3.16k
      }
1510
3.16k
    else if( control == IOBUFCTRL_CANCEL ) {
1511
0
  afx->cancel = 1;
1512
0
    }
1513
3.16k
    else if( control == IOBUFCTRL_FREE ) {
1514
3.16k
  if( afx->cancel )
1515
0
      ;
1516
3.16k
  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.16k
  else if( !afx->any_data && !afx->inp_bypass ) {
1570
1.75k
      log_error(_("no valid OpenPGP data found.\n"));
1571
1.75k
      afx->no_openpgp_data = 1;
1572
1.75k
      write_status_text( STATUS_NODATA, "1" );
1573
1.75k
  }
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.16k
  if( afx->truncated )
1580
3.16k
      log_info(_("invalid armor: line longer than %d characters\n"),
1581
14
          MAX_LINELEN );
1582
  /* issue an error to enforce dissemination of correct software */
1583
3.16k
  if( afx->qp_detected )
1584
3.16k
      log_error(_("quoted printable character in armor - "
1585
61
      "probably a buggy MTA has been used\n") );
1586
3.16k
  xfree( afx->buffer );
1587
3.16k
  afx->buffer = NULL;
1588
3.16k
        release_armor_context (afx);
1589
3.16k
    }
1590
0
    else if( control == IOBUFCTRL_DESC )
1591
0
        mem2str (buf, "armor_filter", *ret_len);
1592
51.0k
    return rc;
1593
51.0k
}
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
}