diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-03-03 13:33:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2023-03-03 13:33:10 +0000 |
commit | 0b130f1b58426a4be60718c64c504bf3700c2778 (patch) | |
tree | fe2422337fe7810369f3fbf772925fb8bc3f6d7b | |
parent | Releasing progress-linux version 5.4.1-1~progress7+u1. (diff) | |
download | reprepro-0b130f1b58426a4be60718c64c504bf3700c2778.tar.xz reprepro-0b130f1b58426a4be60718c64c504bf3700c2778.zip |
Merging upstream version 5.4.2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | NEWS | 5 | ||||
-rw-r--r-- | aptmethod.c | 2 | ||||
-rw-r--r-- | archallflood.c | 1 | ||||
-rw-r--r-- | binaries.c | 2 | ||||
-rw-r--r-- | checksums.c | 54 | ||||
-rw-r--r-- | checksums.h | 5 | ||||
-rw-r--r-- | configparser.h | 2 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | release.c | 2 | ||||
-rw-r--r-- | sha512.c | 309 | ||||
-rw-r--r-- | sha512.h | 20 | ||||
-rw-r--r-- | tool.c | 2 | ||||
-rw-r--r-- | uncompression.c | 35 | ||||
-rw-r--r-- | upgradelist.c | 1 |
16 files changed, 440 insertions, 24 deletions
@@ -1,3 +1,19 @@ +2023-03-01 Bastian Germann <bage@debian.org> + + * configure.ac, NEWS: Release version 5.4.2 + +2023-03-01 Simon Chopin <schopin@ubuntu.com> + + * uncompression.c: uncompress: close the pipe after the child exits + +2022-12-14 Hu Deng <hudeng@uniontech.com> + + * archallflood.c, upgradelist.c: fix: redundant header file + +2022-08-30 Bastian Germann <bage@debian.org> + + Add SHA512 support (Thanks to Hu Deng) + 2022-08-17 Bastian Germann <bage@debian.org> * debfilecontents.c: If data tar extraction fails try again as uncompressed diff --git a/Makefile.am b/Makefile.am index bb55266..5069a5f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -18,14 +18,14 @@ AM_CPPFLAGS = $(ARCHIVECPP) $(DBCPPFLAGS) reprepro_LDADD = $(ARCHIVELIBS) $(DBLIBS) changestool_LDADD = $(ARCHIVELIBS) -reprepro_SOURCES = outhook.c descriptions.c sizes.c sourcecheck.c byhandhook.c archallflood.c needbuild.c globmatch.c printlistformat.c diffindex.c rredpatch.c pool.c atoms.c uncompression.c remoterepository.c indexfile.c copypackages.c sourceextraction.c checksums.c readtextfile.c filecntl.c sha1.c sha256.c configparser.c database.c freespace.c hooks.c log.c changes.c incoming.c uploaderslist.c guesscomponent.c files.c md5.c dirs.c chunks.c reference.c binaries.c sources.c checks.c names.c dpkgversions.c release.c mprintf.c updates.c strlist.c signature_check.c signedfile.c signature.c distribution.c checkindeb.c checkindsc.c checkin.c upgradelist.c target.c aptmethod.c downloadcache.c main.c override.c terms.c termdecide.c ignore.c filterlist.c exports.c tracking.c optionsfile.c donefile.c pull.c contents.c filelist.c $(ARCHIVE_USED) $(ARCHIVE_CONTENTS) +reprepro_SOURCES = outhook.c descriptions.c sizes.c sourcecheck.c byhandhook.c archallflood.c needbuild.c globmatch.c printlistformat.c diffindex.c rredpatch.c pool.c atoms.c uncompression.c remoterepository.c indexfile.c copypackages.c sourceextraction.c checksums.c readtextfile.c filecntl.c sha1.c sha256.c sha512.c configparser.c database.c freespace.c hooks.c log.c changes.c incoming.c uploaderslist.c guesscomponent.c files.c md5.c dirs.c chunks.c reference.c binaries.c sources.c checks.c names.c dpkgversions.c release.c mprintf.c updates.c strlist.c signature_check.c signedfile.c signature.c distribution.c checkindeb.c checkindsc.c checkin.c upgradelist.c target.c aptmethod.c downloadcache.c main.c override.c terms.c termdecide.c ignore.c filterlist.c exports.c tracking.c optionsfile.c donefile.c pull.c contents.c filelist.c $(ARCHIVE_USED) $(ARCHIVE_CONTENTS) EXTRA_reprepro_SOURCE = $(ARCHIVE_UNUSED) -changestool_SOURCES = uncompression.c sourceextraction.c readtextfile.c filecntl.c tool.c chunkedit.c strlist.c checksums.c sha1.c sha256.c md5.c mprintf.c chunks.c signature.c dirs.c names.c $(ARCHIVE_USED) +changestool_SOURCES = uncompression.c sourceextraction.c readtextfile.c filecntl.c tool.c chunkedit.c strlist.c checksums.c sha1.c sha256.c sha512.c md5.c mprintf.c chunks.c signature.c dirs.c names.c $(ARCHIVE_USED) rredtool_SOURCES = rredtool.c rredpatch.c mprintf.c filecntl.c sha1.c -noinst_HEADERS = outhook.h descriptions.h sizes.h sourcecheck.h byhandhook.h archallflood.h needbuild.h globmatch.h printlistformat.h pool.h atoms.h uncompression.h remoterepository.h copypackages.h sourceextraction.h checksums.h readtextfile.h filecntl.h sha1.h sha256.h configparser.h database_p.h database.h freespace.h hooks.h log.h changes.h incoming.h guesscomponent.h md5.h dirs.h files.h chunks.h reference.h binaries.h sources.h checks.h names.h release.h error.h mprintf.h updates.h strlist.h signature.h signature_p.h distribution.h debfile.h checkindeb.h checkindsc.h upgradelist.h target.h aptmethod.h downloadcache.h override.h terms.h termdecide.h ignore.h filterlist.h dpkgversions.h checkin.h exports.h globals.h tracking.h trackingt.h optionsfile.h donefile.h pull.h ar.h filelist.h contents.h chunkedit.h uploaderslist.h indexfile.h rredpatch.h diffindex.h package.h +noinst_HEADERS = outhook.h descriptions.h sizes.h sourcecheck.h byhandhook.h archallflood.h needbuild.h globmatch.h printlistformat.h pool.h atoms.h uncompression.h remoterepository.h copypackages.h sourceextraction.h checksums.h readtextfile.h filecntl.h sha1.h sha256.h sha512.h configparser.h database_p.h database.h freespace.h hooks.h log.h changes.h incoming.h guesscomponent.h md5.h dirs.h files.h chunks.h reference.h binaries.h sources.h checks.h names.h release.h error.h mprintf.h updates.h strlist.h signature.h signature_p.h distribution.h debfile.h checkindeb.h checkindsc.h upgradelist.h target.h aptmethod.h downloadcache.h override.h terms.h termdecide.h ignore.h filterlist.h dpkgversions.h checkin.h exports.h globals.h tracking.h trackingt.h optionsfile.h donefile.h pull.h ar.h filelist.h contents.h chunkedit.h uploaderslist.h indexfile.h rredpatch.h diffindex.h package.h MAINTAINERCLEANFILES = $(srcdir)/Makefile.in $(srcdir)/configure $(srcdir)/stamp-h.in $(srcdir)/aclocal.m4 $(srcdir)/config.h.in @@ -1,3 +1,8 @@ +Updates between 5.4.1 and 5.4.2: +- Add SHA512 support (http://bugs.debian.org/855975) +- uncompress: close the pipe after the child exits + (https://bugs.launchpad.net/ubuntu/+bug/2008508) + Updates between 5.4.0 and 5.4.1: - Add --ignore=conflictingarchall (http://bugs.debian.org/697630) - Add example to notify processing of .changes files (https://bugs.debian.org/827816) diff --git a/aptmethod.c b/aptmethod.c index bcc13cf..e50449b 100644 --- a/aptmethod.c +++ b/aptmethod.c @@ -684,7 +684,7 @@ static inline retvalue gotcapabilities(struct aptmethod *method, const char *chu static inline retvalue goturidone(struct aptmethod *method, const char *chunk) { static const char * const method_hash_names[cs_COUNT] = - { "MD5-Hash", "SHA1-Hash", "SHA256-Hash", + { "MD5-Hash", "SHA1-Hash", "SHA256-Hash", "SHA512-Hash", "Size" }; retvalue result, r; char *uri, *filename; diff --git a/archallflood.c b/archallflood.c index 1a37339..df20247 100644 --- a/archallflood.c +++ b/archallflood.c @@ -18,7 +18,6 @@ #include <stdlib.h> #include <string.h> #include <stdio.h> -#include <stdlib.h> #include <assert.h> #include "error.h" @@ -39,7 +39,7 @@ #include "package.h" static const char * const deb_checksum_headers[cs_COUNT] = { - "MD5sum", "SHA1", "SHA256", "Size"}; + "MD5sum", "SHA1", "SHA256", "SHA512", "Size"}; static char *calc_binary_basename(const char *name, const char *version, architecture_t arch, packagetype_t packagetype) { const char *v; diff --git a/checksums.c b/checksums.c index c228c5e..b3edbd2 100644 --- a/checksums.c +++ b/checksums.c @@ -37,13 +37,13 @@ #include "configparser.h" const char * const changes_checksum_names[] = { - "Files", "Checksums-Sha1", "Checksums-Sha256" + "Files", "Checksums-Sha1", "Checksums-Sha256", "Checksums-Sha512" }; const char * const source_checksum_names[] = { - "Files", "Checksums-Sha1", "Checksums-Sha256" + "Files", "Checksums-Sha1", "Checksums-Sha256", "Checksums-Sha512" }; const char * const release_checksum_names[cs_hashCOUNT] = { - "MD5Sum", "SHA1", "SHA256" + "MD5Sum", "SHA1", "SHA256", "SHA512" }; @@ -74,7 +74,7 @@ struct checksums { static const char * const hash_name[cs_COUNT] = - { "md5", "sha1", "sha256", "size" }; + { "md5", "sha1", "sha256", "sha512", "size" }; void checksums_free(struct checksums *checksums) { free(checksums); @@ -306,6 +306,12 @@ retvalue checksums_parse(struct checksums **checksums_p, const char *combinedche while (*p != ' ' && *p != '\0') *(d++) = *(p++); n->parts[cs_sha256sum].len = (hashlen_t)(d - start); + } else if (type == '3') { + start = d; + n->parts[cs_sha512sum].ofs = d - n->representation; + while (*p != ' ' && *p != '\0') + *(d++) = *(p++); + n->parts[cs_sha512sum].len = (hashlen_t)(d - start); } else { while (*p != ' ' && *p != '\0') *(d++) = *(p++); @@ -525,6 +531,12 @@ retvalue checksums_combine(struct checksums **checksums_p, const struct checksum while (*o != ' ' && *o != '\0') *(d++) = *(o++); n->parts[cs_sha256sum].len = (hashlen_t)(d - start); + } else if (typeid == '3') { + start = d; + n->parts[cs_sha512sum].ofs = d - n->representation; + while (*o != ' ' && *o != '\0') + *(d++) = *(o++); + n->parts[cs_sha512sum].len = (hashlen_t)(d - start); } else while (*o != ' ' && *o != '\0') *(d++) = *(o++); @@ -560,6 +572,14 @@ retvalue checksums_combine(struct checksums **checksums_p, const struct checksum while (*b != ' ' && *b != '\0') *(d++) = *(b++); n->parts[cs_sha256sum].len = (hashlen_t)(d - start); + } else if (typeid == '3') { + if (improvedhashes != NULL) + improvedhashes[cs_sha512sum] = true; + start = d; + n->parts[cs_sha512sum].ofs = d - n->representation; + while (*b != ' ' && *b != '\0') + *(d++) = *(b++); + n->parts[cs_sha512sum].len = (hashlen_t)(d - start); } else while (*b != ' ' && *b != '\0') *(d++) = *(b++); @@ -1126,14 +1146,16 @@ void checksumscontext_init(struct checksumscontext *context) { MD5Init(&context->md5); SHA1Init(&context->sha1); SHA256Init(&context->sha256); + SHA512Init(&context->sha512); } void checksumscontext_update(struct checksumscontext *context, const unsigned char *data, size_t len) { MD5Update(&context->md5, data, len); -// TODO: sha1 and sha256 share quite some stuff, +// TODO: sha1 sha256 and sha512 share quite some stuff, // the code can most likely be combined with quite some synergies.. SHA1Update(&context->sha1, data, len); SHA256Update(&context->sha256, data, len); + SHA512Update(&context->sha512, data, len); } static const char tab[16] = {'0', '1', '2', '3', '4', '5', '6', '7', @@ -1141,13 +1163,13 @@ static const char tab[16] = {'0', '1', '2', '3', '4', '5', '6', '7', retvalue checksums_from_context(struct checksums **out, struct checksumscontext *context) { unsigned char md5buffer[MD5_DIGEST_SIZE], sha1buffer[SHA1_DIGEST_SIZE], - sha256buffer[SHA256_DIGEST_SIZE]; + sha256buffer[SHA256_DIGEST_SIZE], sha512buffer[SHA512_DIGEST_SIZE]; char *d; unsigned int i; struct checksums *n; n = malloc(sizeof(struct checksums) + 2*MD5_DIGEST_SIZE - + 2*SHA1_DIGEST_SIZE + 2*SHA256_DIGEST_SIZE + 30); + + 2*SHA1_DIGEST_SIZE + 2*SHA256_DIGEST_SIZE + 2*SHA512_DIGEST_SIZE + 30); if (FAILEDTOALLOC(n)) return RET_ERROR_OOM; setzero(struct checksums, n); @@ -1176,6 +1198,18 @@ retvalue checksums_from_context(struct checksums **out, struct checksumscontext } *(d++) = ' '; + *(d++) = ':'; + *(d++) = '3'; + *(d++) = ':'; + n->parts[cs_sha512sum].ofs = d - n->representation; + n->parts[cs_sha512sum].len = 2*SHA512_DIGEST_SIZE; + SHA512Final(&context->sha512, sha512buffer); + for (i = 0 ; i < SHA512_DIGEST_SIZE ; i++) { + *(d++) = tab[sha512buffer[i] >> 4]; + *(d++) = tab[sha512buffer[i] & 0xF]; + } + *(d++) = ' '; + n->parts[cs_md5sum].ofs = d - n->representation; assert (d - n->representation == n->parts[cs_md5sum].ofs); n->parts[cs_md5sum].len = 2*MD5_DIGEST_SIZE; @@ -1189,7 +1223,7 @@ retvalue checksums_from_context(struct checksums **out, struct checksumscontext assert (d - n->representation == n->parts[cs_length].ofs); n->parts[cs_length].len = (hashlen_t)snprintf(d, 2*MD5_DIGEST_SIZE + 2*SHA1_DIGEST_SIZE - + 2*SHA256_DIGEST_SIZE + 30 + + 2*SHA256_DIGEST_SIZE + 2*SHA512_DIGEST_SIZE + 30 - (d - n->representation), "%lld", (long long)context->sha1.count); assert (strlen(d) == n->parts[cs_length].len); @@ -1200,7 +1234,8 @@ retvalue checksums_from_context(struct checksums **out, struct checksumscontext bool checksums_iscomplete(const struct checksums *checksums) { return checksums->parts[cs_md5sum].len != 0 && checksums->parts[cs_sha1sum].len != 0 && - checksums->parts[cs_sha256sum].len != 0; + checksums->parts[cs_sha256sum].len != 0 && + checksums->parts[cs_sha512sum].len != 0; } /* Collect missing checksums. @@ -1463,5 +1498,6 @@ const struct constant hashes_constants[cs_hashCOUNT+1] = { {"md5", cs_md5sum}, {"sha1", cs_sha1sum}, {"sha256", cs_sha256sum}, + {"sha512", cs_sha512sum}, {NULL, 0} }, *hashnames = hashes_constants; diff --git a/checksums.h b/checksums.h index 3d0f6f6..8c5da9b 100644 --- a/checksums.h +++ b/checksums.h @@ -16,6 +16,7 @@ enum checksumtype { #define cs_firstEXTENDED cs_sha1sum cs_sha1sum, cs_sha256sum, + cs_sha512sum, #define cs_hashCOUNT cs_length /* must be last but one */ cs_length, @@ -125,11 +126,15 @@ struct configiterator; #ifndef REPREPRO_SHA256_H #include "sha256.h" #endif +#ifndef REPREPRO_SHA512_H +#include "sha512.h" +#endif struct checksumscontext { struct MD5Context md5; struct SHA1_Context sha1; struct SHA256_Context sha256; + struct SHA512_Context sha512; }; void checksumscontext_init(/*@out@*/struct checksumscontext *); diff --git a/configparser.h b/configparser.h index e583b49..c9c3d18 100644 --- a/configparser.h +++ b/configparser.h @@ -263,7 +263,7 @@ static retvalue configparser_ ## sname ## _set_ ## field(UNUSED(void *dummy), co retvalue r; \ item->field ## _set = true; \ r = config_getflags(iter, name, hashnames, item->field, false, \ - "(allowed values: md5, sha1 and sha256)"); \ + "(allowed values: md5, sha1, sha256, and sha512)"); \ if (!RET_IS_OK(r)) \ return r; \ return RET_OK; \ diff --git a/configure.ac b/configure.ac index 8b56f73..77482d5 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ dnl dnl Process this file with autoconf to produce a configure script dnl -AC_INIT(reprepro, 5.4.1) +AC_INIT(reprepro, 5.4.2) AC_CONFIG_SRCDIR(main.c) AC_CONFIG_AUX_DIR(ac) AM_INIT_AUTOMAKE([-Wall -Werror -Wno-portability]) @@ -1573,7 +1573,7 @@ retvalue release_prepare(struct release *release, struct distribution *distribut enum checksumtype cs; int i; static const char * const release_checksum_headers[cs_hashCOUNT] = - { "MD5Sum:\n", "SHA1:\n", "SHA256:\n" }; + { "MD5Sum:\n", "SHA1:\n", "SHA256:\n", "SHA512:\n" }; struct release_entry *plainentry, *signedentry, *detachedentry; // TODO: check for existence of Release file here first? diff --git a/sha512.c b/sha512.c new file mode 100644 index 0000000..1bd942e --- /dev/null +++ b/sha512.c @@ -0,0 +1,309 @@ +/* sha512 implementation, taken (with minor modification) from sha512crypt.c, + which states: + Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>. + Neglegible modifications by Bastian Germann which stem from reprepro's + sha256.c by Bernhard R. Link, also in the public domain. +*/ + +#include <config.h> + +#include <limits.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/param.h> +#include <sys/types.h> + +#include "sha512.h" + +#ifndef WORDS_BIGENDIAN +# define SWAP(n) \ + (((n) << 56) \ + | (((n) & 0xff00) << 40) \ + | (((n) & 0xff0000) << 24) \ + | (((n) & 0xff000000) << 8) \ + | (((n) >> 8) & 0xff000000) \ + | (((n) >> 24) & 0xff0000) \ + | (((n) >> 40) & 0xff00) \ + | ((n) >> 56)) +#else +# define SWAP(n) (n) +#endif + + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (FIPS 180-2:5.1.2) */ +static const unsigned char fillbuf[128] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Constants for SHA512 from FIPS 180-2:4.2.3. */ +static const uint64_t K[80] = + { + UINT64_C (0x428a2f98d728ae22), UINT64_C (0x7137449123ef65cd), + UINT64_C (0xb5c0fbcfec4d3b2f), UINT64_C (0xe9b5dba58189dbbc), + UINT64_C (0x3956c25bf348b538), UINT64_C (0x59f111f1b605d019), + UINT64_C (0x923f82a4af194f9b), UINT64_C (0xab1c5ed5da6d8118), + UINT64_C (0xd807aa98a3030242), UINT64_C (0x12835b0145706fbe), + UINT64_C (0x243185be4ee4b28c), UINT64_C (0x550c7dc3d5ffb4e2), + UINT64_C (0x72be5d74f27b896f), UINT64_C (0x80deb1fe3b1696b1), + UINT64_C (0x9bdc06a725c71235), UINT64_C (0xc19bf174cf692694), + UINT64_C (0xe49b69c19ef14ad2), UINT64_C (0xefbe4786384f25e3), + UINT64_C (0x0fc19dc68b8cd5b5), UINT64_C (0x240ca1cc77ac9c65), + UINT64_C (0x2de92c6f592b0275), UINT64_C (0x4a7484aa6ea6e483), + UINT64_C (0x5cb0a9dcbd41fbd4), UINT64_C (0x76f988da831153b5), + UINT64_C (0x983e5152ee66dfab), UINT64_C (0xa831c66d2db43210), + UINT64_C (0xb00327c898fb213f), UINT64_C (0xbf597fc7beef0ee4), + UINT64_C (0xc6e00bf33da88fc2), UINT64_C (0xd5a79147930aa725), + UINT64_C (0x06ca6351e003826f), UINT64_C (0x142929670a0e6e70), + UINT64_C (0x27b70a8546d22ffc), UINT64_C (0x2e1b21385c26c926), + UINT64_C (0x4d2c6dfc5ac42aed), UINT64_C (0x53380d139d95b3df), + UINT64_C (0x650a73548baf63de), UINT64_C (0x766a0abb3c77b2a8), + UINT64_C (0x81c2c92e47edaee6), UINT64_C (0x92722c851482353b), + UINT64_C (0xa2bfe8a14cf10364), UINT64_C (0xa81a664bbc423001), + UINT64_C (0xc24b8b70d0f89791), UINT64_C (0xc76c51a30654be30), + UINT64_C (0xd192e819d6ef5218), UINT64_C (0xd69906245565a910), + UINT64_C (0xf40e35855771202a), UINT64_C (0x106aa07032bbd1b8), + UINT64_C (0x19a4c116b8d2d0c8), UINT64_C (0x1e376c085141ab53), + UINT64_C (0x2748774cdf8eeb99), UINT64_C (0x34b0bcb5e19b48a8), + UINT64_C (0x391c0cb3c5c95a63), UINT64_C (0x4ed8aa4ae3418acb), + UINT64_C (0x5b9cca4f7763e373), UINT64_C (0x682e6ff3d6b2b8a3), + UINT64_C (0x748f82ee5defb2fc), UINT64_C (0x78a5636f43172f60), + UINT64_C (0x84c87814a1f0ab72), UINT64_C (0x8cc702081a6439ec), + UINT64_C (0x90befffa23631e28), UINT64_C (0xa4506cebde82bde9), + UINT64_C (0xbef9a3f7b2c67915), UINT64_C (0xc67178f2e372532b), + UINT64_C (0xca273eceea26619c), UINT64_C (0xd186b8c721c0c207), + UINT64_C (0xeada7dd6cde0eb1e), UINT64_C (0xf57d4f7fee6ed178), + UINT64_C (0x06f067aa72176fba), UINT64_C (0x0a637dc5a2c898a6), + UINT64_C (0x113f9804bef90dae), UINT64_C (0x1b710b35131c471b), + UINT64_C (0x28db77f523047d84), UINT64_C (0x32caab7b40c72493), + UINT64_C (0x3c9ebe0a15c9bebc), UINT64_C (0x431d67c49c100d4c), + UINT64_C (0x4cc5d4becb3e42b6), UINT64_C (0x597f299cfc657e2a), + UINT64_C (0x5fcb6fab3ad6faec), UINT64_C (0x6c44198c4a475817) + }; + + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 128 == 0. */ +static void +sha512_process_block (const void *buffer, size_t len, struct SHA512_Context *ctx) +{ + const uint64_t *words = buffer; + size_t nwords = len / sizeof (uint64_t); + uint64_t a = ctx->H[0]; + uint64_t b = ctx->H[1]; + uint64_t c = ctx->H[2]; + uint64_t d = ctx->H[3]; + uint64_t e = ctx->H[4]; + uint64_t f = ctx->H[5]; + uint64_t g = ctx->H[6]; + uint64_t h = ctx->H[7]; + + /* First increment the byte count. FIPS 180-2 specifies the possible + length of the file up to 2^128 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 128 bytes in each round of + the loop. */ + while (nwords > 0) + { + uint64_t W[80]; + uint64_t a_save = a; + uint64_t b_save = b; + uint64_t c_save = c; + uint64_t d_save = d; + uint64_t e_save = e; + uint64_t f_save = f; + uint64_t g_save = g; + uint64_t h_save = h; + + /* Operators defined in FIPS 180-2:4.1.2. */ +#define Ch(x, y, z) ((x & y) ^ (~x & z)) +#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z)) +#define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39)) +#define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41)) +#define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7)) +#define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6)) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) ((w >> s) | (w << (64 - s))) + + /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2. */ + for (unsigned int t = 0; t < 16; ++t) + { + W[t] = SWAP (*words); + ++words; + } + for (unsigned int t = 16; t < 80; ++t) + W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16]; + + /* The actual computation according to FIPS 180-2:6.3.2 step 3. */ + for (unsigned int t = 0; t < 80; ++t) + { + uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t]; + uint64_t T2 = S0 (a) + Maj (a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + /* Add the starting values of the context according to FIPS 180-2:6.3.2 + step 4. */ + a += a_save; + b += b_save; + c += c_save; + d += d_save; + e += e_save; + f += f_save; + g += g_save; + h += h_save; + + /* Prepare for the next round. */ + nwords -= 16; + } + + /* Put checksum in context given as argument. */ + ctx->H[0] = a; + ctx->H[1] = b; + ctx->H[2] = c; + ctx->H[3] = d; + ctx->H[4] = e; + ctx->H[5] = f; + ctx->H[6] = g; + ctx->H[7] = h; +} + + +/* Initialize structure containing state of computation. + (FIPS 180-2:5.3.3) */ +void +SHA512Init (struct SHA512_Context *ctx) +{ + ctx->H[0] = UINT64_C (0x6a09e667f3bcc908); + ctx->H[1] = UINT64_C (0xbb67ae8584caa73b); + ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b); + ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1); + ctx->H[4] = UINT64_C (0x510e527fade682d1); + ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f); + ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b); + ctx->H[7] = UINT64_C (0x5be0cd19137e2179); + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to digest. + + IMPORTANT: On some systems it is required that digest is correctly + aligned for a 32 bits value. +*/ +void +SHA512Final (struct SHA512_Context *ctx, uint8_t *digest) +{ + /* Take yet unprocessed bytes into account. */ + uint64_t bytes = ctx->buflen; + size_t pad; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 112 ? 128 + 112 - bytes : 112 - bytes; + memcpy (&ctx->buffer[bytes], fillbuf, pad); + + /* Put the 128-bit file length in *bits* at the end of the buffer. */ + *(uint64_t *) &ctx->buffer[bytes + pad + 8] = SWAP (ctx->total[0] << 3); + *(uint64_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 61)); + + /* Process last bytes. */ + sha512_process_block (ctx->buffer, bytes + pad + 16, ctx); + + for (unsigned int i = 0; i < 8; ++i) + ((uint64_t *) digest)[i] = SWAP (ctx->H[i]); +} + + +void +SHA512Update (struct SHA512_Context *ctx, const uint8_t *buffer, size_t len) +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 256 - left_over > len ? len : 256 - left_over; + + memcpy (&ctx->buffer[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 128) + { + sha512_process_block (ctx->buffer, ctx->buflen & ~127, ctx); + + ctx->buflen &= 127; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~127], + ctx->buflen); + } + + buffer = buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 128) + { +#if !_STRING_ARCH_unaligned +/* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0) +# else +# define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint64_t) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 128) + { + sha512_process_block (memcpy (ctx->buffer, buffer, 128), 128, + ctx); + buffer = buffer + 128; + len -= 128; + } + else +#endif + { + sha512_process_block (buffer, len & ~127, ctx); + buffer = buffer + (len & ~127); + len &= 127; + } + } + + /* Move remaining bytes into internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&ctx->buffer[left_over], buffer, len); + left_over += len; + if (left_over >= 128) + { + sha512_process_block (ctx->buffer, 128, ctx); + left_over -= 128; + memcpy (ctx->buffer, &ctx->buffer[128], left_over); + } + ctx->buflen = left_over; + } +} diff --git a/sha512.h b/sha512.h new file mode 100644 index 0000000..42f822e --- /dev/null +++ b/sha512.h @@ -0,0 +1,20 @@ +#ifndef REPREPRO_SHA512_H +#define REPREPRO_SHA512_H + +/* Structure to save state of computation between the single steps. */ +struct SHA512_Context +{ + uint64_t H[8]; + + uint64_t total[2]; + uint64_t buflen; + char buffer[256]; /* NB: always correctly aligned for uint32_t. */ +}; + +#define SHA512_DIGEST_SIZE 64 + +void SHA512Init(/*@out@*/struct SHA512_Context *context); +void SHA512Update(struct SHA512_Context *context, const uint8_t *data, size_t len); +void SHA512Final(struct SHA512_Context *context, /*@out@*/uint8_t digest[SHA512_DIGEST_SIZE]); + +#endif @@ -559,7 +559,7 @@ static retvalue parse_changes_files(struct changes *c, struct strlist filelines[ return RET_ERROR_OOM; } } - const char * const hashname[cs_hashCOUNT] = {"Md5", "Sha1", "Sha256" }; + const char * const hashname[cs_hashCOUNT] = {"Md5", "Sha1", "Sha256", "Sha512" }; for (cs = cs_firstEXTENDED ; cs < cs_hashCOUNT ; cs++) { tmp = &filelines[cs]; diff --git a/uncompression.c b/uncompression.c index 43819ae..1087b0b 100644 --- a/uncompression.c +++ b/uncompression.c @@ -1422,12 +1422,34 @@ int uncompress_read(struct compressedfile *file, void *buffer, int size) { } } +static inline retvalue drain_pipe_fd(struct compressedfile *file, int *errno_p, const char **msg_p) { + int e = 0; + struct pollfd pollfd = { + file->fd, + POLLIN, + 0 + }; + unsigned char buffer[4096] = {}; + while ((e = poll(&pollfd, 1, 0)) > 0) { + e = read(file->fd, buffer, 4096); + if (e <= 0) + break; + } + if (e < 0) { + *errno_p = e; + *msg_p = strerror(file->error); + return RET_ERRNO(e); + } + return RET_OK; +} + static retvalue uncompress_commonclose(struct compressedfile *file, int *errno_p, const char **msg_p) { retvalue result; int ret; int e; pid_t pid; int status; + int output_fd; #define ERRORBUFFERSIZE 100 static char errorbuffer[ERRORBUFFERSIZE]; @@ -1436,15 +1458,19 @@ static retvalue uncompress_commonclose(struct compressedfile *file, int *errno_p if (file->external) { free(file->intermediate.buffer); - (void)close(file->fd); if (file->pipeinfd != -1) (void)close(file->pipeinfd); + // Drain the child's stdout in the unlikely case it's blocking on it + e = drain_pipe_fd(file, errno_p, msg_p); + if (e != RET_OK) + return e; + output_fd = file->fd; file->fd = file->infd; - file->infd = -1; result = RET_OK; - if (file->pid <= 0) + if (file->pid <= 0) { + (void)close(output_fd); return RET_OK; - pid = -1; + } do { if (interrupted()) { *errno_p = EINTR; @@ -1454,6 +1480,7 @@ static retvalue uncompress_commonclose(struct compressedfile *file, int *errno_p pid = waitpid(file->pid, &status, 0); e = errno; } while (pid == -1 && (e == EINTR || e == EAGAIN)); + (void)close(output_fd); if (pid == -1) { *errno_p = e; *msg_p = strerror(file->error); diff --git a/upgradelist.c b/upgradelist.c index 9634423..be82173 100644 --- a/upgradelist.c +++ b/upgradelist.c @@ -18,7 +18,6 @@ #include <stdlib.h> #include <string.h> #include <stdio.h> -#include <stdlib.h> #include <assert.h> #include "error.h" |