| From db9165814823401d57383a8f9e82642129cf4223 Mon Sep 17 00:00:00 2001 |
| From: Sungbo Eo <mans0n@gorani.run> |
| Date: Sat, 12 Feb 2022 16:42:14 +0900 |
| Subject: [PATCH] make encrypted archives reproducible |
| |
| Zip always try to generate new encryption header depending on execution |
| time and process id, which is far from being reproducible. This commit |
| changes the zip srand() seed to a predictable value to generate |
| reproducible random bytes for the encryption header. This will compromise |
| the goal of secure archive encryption, but it would not be a big problem |
| for our purpose. |
| |
| Signed-off-by: Sungbo Eo <mans0n@gorani.run> |
| --- |
| crypt.c | 8 ++++++-- |
| globals.c | 1 + |
| zip.h | 1 + |
| zipup.c | 2 +- |
| 4 files changed, 9 insertions(+), 3 deletions(-) |
| |
| --- a/crypt.c |
| +++ b/crypt.c |
| @@ -29,7 +29,6 @@ |
| version without encryption capabilities). |
| */ |
| |
| -#define ZCRYPT_INTERNAL |
| #include "zip.h" |
| #include "crypt.h" |
| #include "ttyio.h" |
| @@ -219,7 +218,12 @@ void crypthead(passwd, crc) |
| * often poorly implemented. |
| */ |
| if (++calls == 1) { |
| - srand((unsigned)time(NULL) ^ ZCR_SEED2); |
| + unsigned zcr_seed1 = (unsigned)time(NULL); |
| +#ifndef ZCRYPT_INTERNAL |
| + if (epoch > 0) |
| + zcr_seed1 = (unsigned)epoch; |
| +#endif |
| + srand(zcr_seed1 ^ ZCR_SEED2); |
| } |
| init_keys(passwd); |
| for (n = 0; n < RAND_HEAD_LEN-2; n++) { |
| --- a/globals.c |
| +++ b/globals.c |
| @@ -206,6 +206,7 @@ int read_split_archive = 0; /* 1=s |
| int split_method = 0; /* 0=no splits, 1=seekable, 2=data desc, -1=no */ |
| uzoff_t split_size = 0; /* how big each split should be */ |
| int split_bell = 0; /* when pause for next split ring bell */ |
| +time_t epoch = 0; /* timestamp from SOURCE_DATE_EPOCH */ |
| uzoff_t bytes_prev_splits = 0; /* total bytes written to all splits before this */ |
| uzoff_t bytes_this_entry = 0; /* bytes written for this entry across all splits */ |
| int noisy_splits = 0; /* note when splits are being created */ |
| --- a/zip.h |
| +++ b/zip.h |
| @@ -502,6 +502,7 @@ extern uzoff_t bytes_this_split; /* byte |
| extern int read_split_archive; /* 1=scanzipf_reg detected spanning signature */ |
| extern int split_method; /* 0=no splits, 1=seekable, 2=data descs, -1=no */ |
| extern uzoff_t split_size; /* how big each split should be */ |
| +extern time_t epoch; /* timestamp from SOURCE_DATE_EPOCH */ |
| extern int split_bell; /* when pause for next split ring bell */ |
| extern uzoff_t bytes_prev_splits; /* total bytes written to all splits before this */ |
| extern uzoff_t bytes_this_entry; /* bytes written for this entry across all splits */ |
| --- a/zipup.c |
| +++ b/zipup.c |
| @@ -676,7 +676,7 @@ struct zlist far *z; /* zip entry to |
| } /* strcmp(z->name, "-") == 0 */ |
| |
| if (extra_fields == 0 && (source_date_epoch = getenv("SOURCE_DATE_EPOCH")) != NULL) { |
| - time_t epoch = strtoull(source_date_epoch, NULL, 10); |
| + epoch = strtoull(source_date_epoch, NULL, 10); |
| if (epoch > 0) { |
| ulg epochtim = unix2dostime(&epoch); |
| if (z->tim > epochtim) z->tim = epochtim; |