012-make-encrypted-archives-reproducible.patch 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. From db9165814823401d57383a8f9e82642129cf4223 Mon Sep 17 00:00:00 2001
  2. From: Sungbo Eo <mans0n@gorani.run>
  3. Date: Sat, 12 Feb 2022 16:42:14 +0900
  4. Subject: [PATCH] make encrypted archives reproducible
  5. Zip always try to generate new encryption header depending on execution
  6. time and process id, which is far from being reproducible. This commit
  7. changes the zip srand() seed to a predictable value to generate
  8. reproducible random bytes for the encryption header. This will compromise
  9. the goal of secure archive encryption, but it would not be a big problem
  10. for our purpose.
  11. Signed-off-by: Sungbo Eo <mans0n@gorani.run>
  12. ---
  13. crypt.c | 8 ++++++--
  14. globals.c | 1 +
  15. zip.h | 1 +
  16. zipup.c | 2 +-
  17. 4 files changed, 9 insertions(+), 3 deletions(-)
  18. --- a/crypt.c
  19. +++ b/crypt.c
  20. @@ -29,7 +29,6 @@
  21. version without encryption capabilities).
  22. */
  23. -#define ZCRYPT_INTERNAL
  24. #include "zip.h"
  25. #include "crypt.h"
  26. #include "ttyio.h"
  27. @@ -219,7 +218,12 @@ void crypthead(passwd, crc)
  28. * often poorly implemented.
  29. */
  30. if (++calls == 1) {
  31. - srand((unsigned)time(NULL) ^ ZCR_SEED2);
  32. + unsigned zcr_seed1 = (unsigned)time(NULL);
  33. +#ifndef ZCRYPT_INTERNAL
  34. + if (epoch > 0)
  35. + zcr_seed1 = (unsigned)epoch;
  36. +#endif
  37. + srand(zcr_seed1 ^ ZCR_SEED2);
  38. }
  39. init_keys(passwd);
  40. for (n = 0; n < RAND_HEAD_LEN-2; n++) {
  41. --- a/globals.c
  42. +++ b/globals.c
  43. @@ -206,6 +206,7 @@ int read_split_archive = 0; /* 1=s
  44. int split_method = 0; /* 0=no splits, 1=seekable, 2=data desc, -1=no */
  45. uzoff_t split_size = 0; /* how big each split should be */
  46. int split_bell = 0; /* when pause for next split ring bell */
  47. +time_t epoch = 0; /* timestamp from SOURCE_DATE_EPOCH */
  48. uzoff_t bytes_prev_splits = 0; /* total bytes written to all splits before this */
  49. uzoff_t bytes_this_entry = 0; /* bytes written for this entry across all splits */
  50. int noisy_splits = 0; /* note when splits are being created */
  51. --- a/zip.h
  52. +++ b/zip.h
  53. @@ -502,6 +502,7 @@ extern uzoff_t bytes_this_split; /* byte
  54. extern int read_split_archive; /* 1=scanzipf_reg detected spanning signature */
  55. extern int split_method; /* 0=no splits, 1=seekable, 2=data descs, -1=no */
  56. extern uzoff_t split_size; /* how big each split should be */
  57. +extern time_t epoch; /* timestamp from SOURCE_DATE_EPOCH */
  58. extern int split_bell; /* when pause for next split ring bell */
  59. extern uzoff_t bytes_prev_splits; /* total bytes written to all splits before this */
  60. extern uzoff_t bytes_this_entry; /* bytes written for this entry across all splits */
  61. --- a/zipup.c
  62. +++ b/zipup.c
  63. @@ -676,7 +676,7 @@ struct zlist far *z; /* zip entry to
  64. } /* strcmp(z->name, "-") == 0 */
  65. if (extra_fields == 0 && (source_date_epoch = getenv("SOURCE_DATE_EPOCH")) != NULL) {
  66. - time_t epoch = strtoull(source_date_epoch, NULL, 10);
  67. + epoch = strtoull(source_date_epoch, NULL, 10);
  68. if (epoch > 0) {
  69. ulg epochtim = unix2dostime(&epoch);
  70. if (z->tim > epochtim) z->tim = epochtim;