gnupg-2.4.2-fix-emacs.patch (16897B)
1 https://bugs.gentoo.org/907839 2 https://dev.gnupg.org/T6481 3 https://git.gnupg.org/cgi-bin/gitweb.cgi?p=gnupg.git;a=commit;h=2f872fa68c6576724b9dabee9fb0844266f55d0d 4 5 From 2f872fa68c6576724b9dabee9fb0844266f55d0d Mon Sep 17 00:00:00 2001 6 From: NIIBE Yutaka <gniibe@fsij.org> 7 Date: Wed, 24 May 2023 10:36:04 +0900 8 Subject: [PATCH] gpg: Report BEGIN_* status before examining the input. 9 10 * common/miscellaneous.c (is_openpgp_compressed_packet) 11 (is_file_compressed): Moved to ... 12 * common/iobuf.c: ... in this file. 13 (is_file_compressed): Change the argument to INP, the iobuf. 14 * common/util.h (is_file_compressed): Remove. 15 * common/iobuf.h (is_file_compressed): Add. 16 * g10/cipher-aead.c (write_header): Don't call write_status_printf 17 here. 18 (cipher_filter_aead): Call write_status_printf when called with 19 IOBUFCTRL_INIT. 20 * g10/cipher-cfb.c (write_header): Don't call write_status_printf 21 here. 22 (cipher_filter_cfb): Call write_status_printf when called with 23 IOBUFCTRL_INIT. 24 * g10/encrypt.c (encrypt_simple): Use new is_file_compressed function, 25 after call of iobuf_push_filter. 26 (encrypt_crypt): Likewise. 27 * g10/sign.c (sign_file): Likewise. 28 29 -- 30 31 GnuPG-bug-id: 6481 32 Signed-off-by: NIIBE Yutaka <gniibe@fsij.org> 33 --- a/common/iobuf.c 34 +++ b/common/iobuf.c 35 @@ -3057,3 +3057,123 @@ iobuf_skip_rest (iobuf_t a, unsigned long n, int partial) 36 } 37 } 38 } 39 + 40 + 41 +/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed 42 + * packet. LEN should be at least 6. */ 43 +static int 44 +is_openpgp_compressed_packet (const unsigned char *buf, size_t len) 45 +{ 46 + int c, ctb, pkttype; 47 + int lenbytes; 48 + 49 + ctb = *buf++; len--; 50 + if (!(ctb & 0x80)) 51 + return 0; /* Invalid packet. */ 52 + 53 + if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */ 54 + { 55 + pkttype = (ctb & 0x3f); 56 + if (!len) 57 + return 0; /* Expected first length octet missing. */ 58 + c = *buf++; len--; 59 + if (c < 192) 60 + ; 61 + else if (c < 224) 62 + { 63 + if (!len) 64 + return 0; /* Expected second length octet missing. */ 65 + } 66 + else if (c == 255) 67 + { 68 + if (len < 4) 69 + return 0; /* Expected length octets missing */ 70 + } 71 + } 72 + else /* Old style CTB. */ 73 + { 74 + pkttype = (ctb>>2)&0xf; 75 + lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); 76 + if (len < lenbytes) 77 + return 0; /* Not enough length bytes. */ 78 + } 79 + 80 + return (pkttype == 8); 81 +} 82 + 83 + 84 +/* 85 + * Check if the file is compressed, by peeking the iobuf. You need to 86 + * pass the iobuf with INP. Returns true if the buffer seems to be 87 + * compressed. 88 + */ 89 +int 90 +is_file_compressed (iobuf_t inp) 91 +{ 92 + int i; 93 + char buf[32]; 94 + int buflen; 95 + 96 + struct magic_compress_s 97 + { 98 + byte len; 99 + byte extchk; 100 + byte magic[5]; 101 + } magic[] = 102 + { 103 + { 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */ 104 + { 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */ 105 + { 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */ 106 + { 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */ 107 + { 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */ 108 + { 5, 2, { 0x89, 'P','N','G', 0x0d} } /* Likely PNG */ 109 + }; 110 + 111 + if (!inp) 112 + return 0; 113 + 114 + for ( ; inp->chain; inp = inp->chain ) 115 + ; 116 + 117 + buflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof buf, buf); 118 + if (buflen < 0) 119 + { 120 + buflen = 0; 121 + log_debug ("peeking at input failed\n"); 122 + } 123 + 124 + if ( buflen < 6 ) 125 + { 126 + return 0; /* Too short to check - assume uncompressed. */ 127 + } 128 + 129 + for ( i = 0; i < DIM (magic); i++ ) 130 + { 131 + if (!memcmp( buf, magic[i].magic, magic[i].len)) 132 + { 133 + switch (magic[i].extchk) 134 + { 135 + case 0: 136 + return 1; /* Is compressed. */ 137 + case 1: 138 + if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5)) 139 + return 1; /* JFIF: this likely a compressed JPEG. */ 140 + break; 141 + case 2: 142 + if (buflen > 8 143 + && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) 144 + return 1; /* This is a PNG. */ 145 + break; 146 + default: 147 + break; 148 + } 149 + } 150 + } 151 + 152 + if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen)) 153 + { 154 + return 1; /* Already compressed. */ 155 + } 156 + 157 + return 0; /* Not detected as compressed. */ 158 +} 159 --- a/common/iobuf.h 160 +++ b/common/iobuf.h 161 @@ -629,6 +629,9 @@ void iobuf_set_partial_body_length_mode (iobuf_t a, size_t len); 162 from the following filter (which may or may not return EOF). */ 163 void iobuf_skip_rest (iobuf_t a, unsigned long n, int partial); 164 165 +/* Check if the file is compressed, by peeking the iobuf. */ 166 +int is_file_compressed (iobuf_t inp); 167 + 168 #define iobuf_where(a) "[don't know]" 169 170 /* Each time a filter is allocated (via iobuf_alloc()), a 171 --- a/common/miscellaneous.c 172 +++ b/common/miscellaneous.c 173 @@ -415,112 +415,6 @@ decode_c_string (const char *src) 174 } 175 176 177 -/* Check whether (BUF,LEN) is valid header for an OpenPGP compressed 178 - * packet. LEN should be at least 6. */ 179 -static int 180 -is_openpgp_compressed_packet (const unsigned char *buf, size_t len) 181 -{ 182 - int c, ctb, pkttype; 183 - int lenbytes; 184 - 185 - ctb = *buf++; len--; 186 - if (!(ctb & 0x80)) 187 - return 0; /* Invalid packet. */ 188 - 189 - if ((ctb & 0x40)) /* New style (OpenPGP) CTB. */ 190 - { 191 - pkttype = (ctb & 0x3f); 192 - if (!len) 193 - return 0; /* Expected first length octet missing. */ 194 - c = *buf++; len--; 195 - if (c < 192) 196 - ; 197 - else if (c < 224) 198 - { 199 - if (!len) 200 - return 0; /* Expected second length octet missing. */ 201 - } 202 - else if (c == 255) 203 - { 204 - if (len < 4) 205 - return 0; /* Expected length octets missing */ 206 - } 207 - } 208 - else /* Old style CTB. */ 209 - { 210 - pkttype = (ctb>>2)&0xf; 211 - lenbytes = ((ctb&3)==3)? 0 : (1<<(ctb & 3)); 212 - if (len < lenbytes) 213 - return 0; /* Not enough length bytes. */ 214 - } 215 - 216 - return (pkttype == 8); 217 -} 218 - 219 - 220 - 221 -/* 222 - * Check if the file is compressed. You need to pass the first bytes 223 - * of the file as (BUF,BUFLEN). Returns true if the buffer seems to 224 - * be compressed. 225 - */ 226 -int 227 -is_file_compressed (const byte *buf, unsigned int buflen) 228 -{ 229 - int i; 230 - 231 - struct magic_compress_s 232 - { 233 - byte len; 234 - byte extchk; 235 - byte magic[5]; 236 - } magic[] = 237 - { 238 - { 3, 0, { 0x42, 0x5a, 0x68, 0x00 } }, /* bzip2 */ 239 - { 3, 0, { 0x1f, 0x8b, 0x08, 0x00 } }, /* gzip */ 240 - { 4, 0, { 0x50, 0x4b, 0x03, 0x04 } }, /* (pk)zip */ 241 - { 5, 0, { '%', 'P', 'D', 'F', '-'} }, /* PDF */ 242 - { 4, 1, { 0xff, 0xd8, 0xff, 0xe0 } }, /* Maybe JFIF */ 243 - { 5, 2, { 0x89, 'P','N','G', 0x0d} } /* Likely PNG */ 244 - }; 245 - 246 - if ( buflen < 6 ) 247 - { 248 - return 0; /* Too short to check - assume uncompressed. */ 249 - } 250 - 251 - for ( i = 0; i < DIM (magic); i++ ) 252 - { 253 - if (!memcmp( buf, magic[i].magic, magic[i].len)) 254 - { 255 - switch (magic[i].extchk) 256 - { 257 - case 0: 258 - return 1; /* Is compressed. */ 259 - case 1: 260 - if (buflen > 11 && !memcmp (buf + 6, "JFIF", 5)) 261 - return 1; /* JFIF: this likely a compressed JPEG. */ 262 - break; 263 - case 2: 264 - if (buflen > 8 265 - && buf[5] == 0x0a && buf[6] == 0x1a && buf[7] == 0x0a) 266 - return 1; /* This is a PNG. */ 267 - break; 268 - default: 269 - break; 270 - } 271 - } 272 - } 273 - 274 - if (buflen >= 6 && is_openpgp_compressed_packet (buf, buflen)) 275 - { 276 - return 1; /* Already compressed. */ 277 - } 278 - 279 - return 0; /* Not detected as compressed. */ 280 -} 281 - 282 - 283 /* Try match against each substring of multistr, delimited by | */ 284 int 285 match_multistr (const char *multistr,const char *match) 286 --- a/common/util.h 287 +++ b/common/util.h 288 @@ -360,8 +360,6 @@ char *try_make_printable_string (const void *p, size_t n, int delim); 289 char *make_printable_string (const void *p, size_t n, int delim); 290 char *decode_c_string (const char *src); 291 292 -int is_file_compressed (const byte *buf, unsigned int buflen); 293 - 294 int match_multistr (const char *multistr,const char *match); 295 296 int gnupg_compare_version (const char *a, const char *b); 297 --- a/g10/cipher-aead.c 298 +++ b/g10/cipher-aead.c 299 @@ -174,8 +174,6 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) 300 log_debug ("aead packet: len=%lu extralen=%d\n", 301 (unsigned long)ed.len, ed.extralen); 302 303 - write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d", 304 - cfx->dek->algo, ed.aead_algo); 305 print_cipher_algo_note (cfx->dek->algo); 306 307 if (build_packet( a, &pkt)) 308 @@ -488,6 +486,11 @@ cipher_filter_aead (void *opaque, int control, 309 { 310 mem2str (buf, "cipher_filter_aead", *ret_len); 311 } 312 + else if (control == IOBUFCTRL_INIT) 313 + { 314 + write_status_printf (STATUS_BEGIN_ENCRYPTION, "0 %d %d", 315 + cfx->dek->algo, cfx->dek->use_aead); 316 + } 317 318 return rc; 319 } 320 --- a/g10/cipher-cfb.c 321 +++ b/g10/cipher-cfb.c 322 @@ -72,9 +72,6 @@ write_header (cipher_filter_context_t *cfx, iobuf_t a) 323 log_info (_("Hint: Do not use option %s\n"), "--rfc2440"); 324 } 325 326 - write_status_printf (STATUS_BEGIN_ENCRYPTION, "%d %d", 327 - ed.mdc_method, cfx->dek->algo); 328 - 329 init_packet (&pkt); 330 pkt.pkttype = cfx->dek->use_mdc? PKT_ENCRYPTED_MDC : PKT_ENCRYPTED; 331 pkt.pkt.encrypted = &ed; 332 @@ -182,6 +179,12 @@ cipher_filter_cfb (void *opaque, int control, 333 { 334 mem2str (buf, "cipher_filter_cfb", *ret_len); 335 } 336 + else if (control == IOBUFCTRL_INIT) 337 + { 338 + write_status_printf (STATUS_BEGIN_ENCRYPTION, "%d %d", 339 + cfx->dek->use_mdc ? DIGEST_ALGO_SHA1 : 0, 340 + cfx->dek->algo); 341 + } 342 343 return rc; 344 } 345 --- a/g10/encrypt.c 346 +++ b/g10/encrypt.c 347 @@ -410,8 +410,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) 348 text_filter_context_t tfx; 349 progress_filter_context_t *pfx; 350 int do_compress = !!default_compress_algo(); 351 - char peekbuf[32]; 352 - int peekbuflen; 353 354 if (!gnupg_rng_is_compliant (opt.compliance)) 355 { 356 @@ -448,14 +446,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) 357 return rc; 358 } 359 360 - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); 361 - if (peekbuflen < 0) 362 - { 363 - peekbuflen = 0; 364 - if (DBG_FILTER) 365 - log_debug ("peeking at input failed\n"); 366 - } 367 - 368 handle_progress (pfx, inp, filename); 369 370 if (opt.textmode) 371 @@ -517,17 +507,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) 372 /**/ : "CFB"); 373 } 374 375 - if (do_compress 376 - && cfx.dek 377 - && (cfx.dek->use_mdc || cfx.dek->use_aead) 378 - && !opt.explicit_compress_option 379 - && is_file_compressed (peekbuf, peekbuflen)) 380 - { 381 - if (opt.verbose) 382 - log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); 383 - do_compress = 0; 384 - } 385 - 386 if ( rc || (rc = open_outfile (-1, filename, opt.armor? 1:0, 0, &out ))) 387 { 388 iobuf_cancel (inp); 389 @@ -598,6 +577,24 @@ encrypt_simple (const char *filename, int mode, int use_seskey) 390 else 391 filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ 392 393 + /* Register the cipher filter. */ 394 + if (mode) 395 + iobuf_push_filter (out, 396 + cfx.dek->use_aead? cipher_filter_aead 397 + /**/ : cipher_filter_cfb, 398 + &cfx ); 399 + 400 + if (do_compress 401 + && cfx.dek 402 + && (cfx.dek->use_mdc || cfx.dek->use_aead) 403 + && !opt.explicit_compress_option 404 + && is_file_compressed (inp)) 405 + { 406 + if (opt.verbose) 407 + log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); 408 + do_compress = 0; 409 + } 410 + 411 if (!opt.no_literal) 412 { 413 /* Note that PT has been initialized above in !no_literal mode. */ 414 @@ -617,13 +614,6 @@ encrypt_simple (const char *filename, int mode, int use_seskey) 415 pkt.pkt.generic = NULL; 416 } 417 418 - /* Register the cipher filter. */ 419 - if (mode) 420 - iobuf_push_filter (out, 421 - cfx.dek->use_aead? cipher_filter_aead 422 - /**/ : cipher_filter_cfb, 423 - &cfx ); 424 - 425 /* Register the compress filter. */ 426 if ( do_compress ) 427 { 428 @@ -783,7 +773,7 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, 429 PKT_plaintext *pt = NULL; 430 DEK *symkey_dek = NULL; 431 STRING2KEY *symkey_s2k = NULL; 432 - int rc = 0, rc2 = 0; 433 + int rc = 0; 434 u32 filesize; 435 cipher_filter_context_t cfx; 436 armor_filter_context_t *afx = NULL; 437 @@ -792,8 +782,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, 438 progress_filter_context_t *pfx; 439 PK_LIST pk_list; 440 int do_compress; 441 - char peekbuf[32]; 442 - int peekbuflen; 443 444 if (filefd != -1 && filename) 445 return gpg_error (GPG_ERR_INV_ARG); /* Both given. */ 446 @@ -866,14 +854,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, 447 if (opt.verbose) 448 log_info (_("reading from '%s'\n"), iobuf_get_fname_nonnull (inp)); 449 450 - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); 451 - if (peekbuflen < 0) 452 - { 453 - peekbuflen = 0; 454 - if (DBG_FILTER) 455 - log_debug ("peeking at input failed\n"); 456 - } 457 - 458 handle_progress (pfx, inp, filename); 459 460 if (opt.textmode) 461 @@ -900,25 +880,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, 462 if (!cfx.dek->use_aead) 463 cfx.dek->use_mdc = !!use_mdc (pk_list, cfx.dek->algo); 464 465 - /* Only do the is-file-already-compressed check if we are using a 466 - * MDC or AEAD. This forces compressed files to be re-compressed if 467 - * we do not have a MDC to give some protection against chosen 468 - * ciphertext attacks. */ 469 - if (do_compress 470 - && (cfx.dek->use_mdc || cfx.dek->use_aead) 471 - && !opt.explicit_compress_option 472 - && is_file_compressed (peekbuf, peekbuflen)) 473 - { 474 - if (opt.verbose) 475 - log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); 476 - do_compress = 0; 477 - } 478 - if (rc2) 479 - { 480 - rc = rc2; 481 - goto leave; 482 - } 483 - 484 make_session_key (cfx.dek); 485 if (DBG_CRYPTO) 486 log_printhex (cfx.dek->key, cfx.dek->keylen, "DEK is: "); 487 @@ -960,6 +921,26 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, 488 else 489 filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */ 490 491 + /* Register the cipher filter. */ 492 + iobuf_push_filter (out, 493 + cfx.dek->use_aead? cipher_filter_aead 494 + /**/ : cipher_filter_cfb, 495 + &cfx); 496 + 497 + /* Only do the is-file-already-compressed check if we are using a 498 + * MDC or AEAD. This forces compressed files to be re-compressed if 499 + * we do not have a MDC to give some protection against chosen 500 + * ciphertext attacks. */ 501 + if (do_compress 502 + && (cfx.dek->use_mdc || cfx.dek->use_aead) 503 + && !opt.explicit_compress_option 504 + && is_file_compressed (inp)) 505 + { 506 + if (opt.verbose) 507 + log_info(_("'%s' already compressed\n"), filename? filename: "[stdin]"); 508 + do_compress = 0; 509 + } 510 + 511 if (!opt.no_literal) 512 { 513 pt->timestamp = make_timestamp(); 514 @@ -974,12 +955,6 @@ encrypt_crypt (ctrl_t ctrl, int filefd, const char *filename, 515 else 516 cfx.datalen = filesize && !do_compress ? filesize : 0; 517 518 - /* Register the cipher filter. */ 519 - iobuf_push_filter (out, 520 - cfx.dek->use_aead? cipher_filter_aead 521 - /**/ : cipher_filter_cfb, 522 - &cfx); 523 - 524 /* Register the compress filter. */ 525 if (do_compress) 526 { 527 --- a/g10/sign.c 528 +++ b/g10/sign.c 529 @@ -1035,9 +1035,6 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, 530 int multifile = 0; 531 u32 duration=0; 532 pt_extra_hash_data_t extrahash = NULL; 533 - char peekbuf[32]; 534 - int peekbuflen = 0; 535 - 536 537 pfx = new_progress_context (); 538 afx = new_armor_context (); 539 @@ -1096,14 +1093,6 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, 540 goto leave; 541 } 542 543 - peekbuflen = iobuf_ioctl (inp, IOBUF_IOCTL_PEEK, sizeof peekbuf, peekbuf); 544 - if (peekbuflen < 0) 545 - { 546 - peekbuflen = 0; 547 - if (DBG_FILTER) 548 - log_debug ("peeking at input failed\n"); 549 - } 550 - 551 handle_progress (pfx, inp, fname); 552 } 553 554 @@ -1261,7 +1250,7 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, 555 int compr_algo = opt.compress_algo; 556 557 if (!opt.explicit_compress_option 558 - && is_file_compressed (peekbuf, peekbuflen)) 559 + && is_file_compressed (inp)) 560 { 561 if (opt.verbose) 562 log_info(_("'%s' already compressed\n"), fname? fname: "[stdin]"); 563 -- 564 2.11.0