diff --git a/utils/Makefile b/utils/Makefile index f8bae179e78..28a764c8b46 100644 --- a/utils/Makefile +++ b/utils/Makefile @@ -1,18 +1,30 @@ -CFLAGS += -Wall -Werror -O3 -funroll-all-loops -ftree-loop-linear PREFIX ?= /usr/local -PKGDB_CFLAGS += -Wall -Werror -I$(PREFIX)/include -PKGDB_LDFLAGS += -lprop +CFLAGS += -Wall -Werror -O3 -I$(PREFIX)/include +CFLAGS += -funroll-all-loops -ftree-loop-linear +LDFLAGS += -lprop -all: xbps-digest xbps-pkgdb xbps-cmpver clean_objs +all: xbps_digest xbps_pkgdb xbps-cmpver clean_objs xbps-cmpver: xbps-cmpver.o $(CC) $(CFLAGS) $< -o $@ -xbps-digest: xbps-digest.o - $(CC) $(CFLAGS) $< -o $@ +sha256_digest: sha256_digest.o + $(CC) $(CFLAGS) -c $@ -xbps-pkgdb: xbps-pkgdb.o - $(CC) $(PKGDB_CFLAGS) $(CFLAGS) $(PKGDB_LDFLAGS) $< -o $@ +xbps-digest: xbps-digest.o + $(CC) $(CFLAGS) -c $@ + +xbps_digest: xbps-digest.o sha256_digest.o + $(CC) $(LDFLAGS) -o xbps-digest xbps-digest.o sha256_digest.o + +xbps-pkgdb: + $(CC) $(CFLAGS) -c $@ + +plist_utils: + $(CC) $(CFLAGS) -c $@ + +xbps_pkgdb: xbps-pkgdb.o plist_utils.o + $(CC) $(LDFLAGS) -o xbps-pkgdb xbps-pkgdb.o plist_utils.o clean_objs: -rm -f *.o diff --git a/utils/plist_utils.c b/utils/plist_utils.c new file mode 100644 index 00000000000..ef6488394df --- /dev/null +++ b/utils/plist_utils.c @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2008 Juan Romero Pardines. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "plist_utils.h" + +prop_dictionary_t +xbps_find_pkg_in_dict(prop_dictionary_t dict, const char *key, + const char *pkgname) +{ + prop_array_t array; + prop_object_iterator_t iter; + prop_object_t obj; + const char *dpkgn; + + if (dict == NULL || pkgname == NULL || key == NULL) + return NULL; + + array = prop_dictionary_get(dict, key); + if (array == NULL || prop_object_type(array) != PROP_TYPE_ARRAY) + return NULL; + + iter = prop_array_iterator(array); + if (iter == NULL) + return NULL; + + while ((obj = prop_object_iterator_next(iter))) { + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &dpkgn); + if (strcmp(dpkgn, pkgname) == 0) + break; + } + prop_object_iterator_release(iter); + + return obj; +} + +bool +xbps_add_obj_to_array(prop_array_t array, prop_object_t obj) +{ + if (array == NULL || obj == NULL) + return false; + + if (!prop_array_add(array, obj)) { + prop_object_release(array); + return false; + } + + prop_object_release(obj); + return true; +} + +bool +xbps_add_array_to_dict(prop_dictionary_t dict, prop_array_t array, + const char *key) +{ + if (dict == NULL || array == NULL || key == NULL) + return false; + + if (!prop_dictionary_set(dict, key, array)) + return false; + + prop_object_release(array); + return true; +} + +void +xbps_list_pkgs_in_dict(prop_dictionary_t dict, const char *key) +{ + prop_array_t array; + prop_object_t obj; + prop_object_iterator_t iter; + const char *pkgname, *version, *short_desc; + + if (dict == NULL || key == NULL) { + printf("%s: NULL dict/key\n", __func__); + exit(1); + } + + array = prop_dictionary_get(dict, key); + if (array == NULL || prop_object_type(array) != PROP_TYPE_ARRAY) { + printf("%s: NULL or incorrect array type\n", __func__); + exit(1); + } + + iter = prop_array_iterator(array); + if (iter == NULL) { + printf("%s: NULL iter\n", __func__); + exit(1); + } + + while ((obj = prop_object_iterator_next(iter))) { + prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); + prop_dictionary_get_cstring_nocopy(obj, "version", &version); + prop_dictionary_get_cstring_nocopy(obj, "short_desc", + &short_desc); + if (pkgname && version && short_desc) + printf("%s (%s)\t%s\n", pkgname, version, short_desc); + } + + prop_object_iterator_release(iter); +} diff --git a/utils/plist_utils.h b/utils/plist_utils.h new file mode 100644 index 00000000000..f9afed13cb4 --- /dev/null +++ b/utils/plist_utils.h @@ -0,0 +1,78 @@ +/*- + * Copyright (c) 2008 Juan Romero Pardines. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XBPS_PLIST_UTILS_H_ +#define _XBPS_PLIST_UTILS_H_ + +/* + * Adds an array object with specified key into a dictionary. + * + * Arguments: + * - prop_dictionary_t: dictionary to store the array. + * - prop_array_t: the array to be stored. + * - const char *: the key associated with the array. + * + * Returns true on success, false on failure. + */ +bool +xbps_add_array_to_dict(prop_dictionary_t, prop_array_t, const char *); + +/* + * Adds an opaque object into an array. + * + * Arguments: + * - prop_array_t: the array storing the object. + * - prop_object_t: the opaque object to be stored. + * + * Returns true on success, false on failure. + */ +bool +xbps_add_obj_to_array(prop_array_t, prop_object_t); + +/* + * Finds a package's dictionary into the main dictionary. + * + * Arguments: + * - prop_dictionary_t: main dictionary to search the object. + * - 1st const char *key: use a dictionary with that key. + * - 2nd const char *pkgname: string of package name. + * + * Returns the package's dictionary object, otherwise NULL. + */ +prop_dictionary_t +xbps_find_pkg_in_dict(prop_dictionary_t, const char *, const char *); + +/* + * Lists information about all packages found in a dictionary, by + * using a triplet: pkgname, version and short_desc. + * + * Arguments: + * - prop_dictionary_t: dictionary where to search on. + * - const char *: the key associated with the dictionary. + */ +void +xbps_list_pkgs_in_dict(prop_dictionary_t, const char *); + +#endif /* !_XBPS_PLIST_UTILS_H_ */ diff --git a/utils/sh/binpkg-genindex.sh b/utils/sh/binpkg-genindex.sh index 08b071deda3..e17e8d86ded 100644 --- a/utils/sh/binpkg-genindex.sh +++ b/utils/sh/binpkg-genindex.sh @@ -74,6 +74,8 @@ write_repo_pkgindex() write_repo_pkgindex_footer $pkgindexf if [ $? -eq 0 ]; then + $XBPS_REGPKGDB_CMD sanitize-plist $pkgindexf + [ $? -ne 0 ] && rm -f $pkgindexf && rm -rf $tmppkgdir && exit 1 msg_normal "Package index created (total pkgs: $pkgsum)." cp -f $pkgindexf $XBPS_PACKAGESDIR/pkg-index.plist fi @@ -92,8 +94,8 @@ write_repo_pkgindex_header() - xbps_available_packages - +xbps_available_packages + _EOF } @@ -104,7 +106,7 @@ write_repo_pkgindex_footer() [ -z "$file" ] && return 1 cat >> $file <<_EOF - + _EOF @@ -121,7 +123,6 @@ write_repo_pkgindex_dict() local indexf="$2" local binpkgf="$3" local first_dict= - local array_found= local tmpdictf= [ -z "$pkgf" -o -z "$indexf" -o -z "$binpkgf" ] && return 1 @@ -132,10 +133,10 @@ write_repo_pkgindex_dict() # Find the first dictionary. if $(echo $line|grep -q ""); then first_dict=yes - printf "\t\t$line\n" >> $tmpdictf + echo "$line" >> $tmpdictf # Write the binary pkg filename before. - printf "\t\t\tfilename\n" >> $tmpdictf - printf "\t\t\t$binpkgf\n" >> $tmpdictf + echo "filename" >> $tmpdictf + echo "$binpkgf" >> $tmpdictf continue # Continue until found. elif [ -z "$first_dict" ]; then @@ -143,29 +144,10 @@ write_repo_pkgindex_dict() # Is this line the end of dictionary? elif $(echo $line|grep -q ""); then # It is. - printf "\t\t$line\n" >> $tmpdictf + echo "$line" >> $tmpdictf break - # Is this line the start of an array? - elif $(echo $line|grep -q ""); then - # It is. - array_found=yes - printf "\t\t\t$line\n" >> $tmpdictf - continue - # Is this line the end of array? - elif $(echo $line|grep -q ""); then - # It is. - printf "\t\t\t$line\n" >> $tmpdictf - unset array_found - continue - # Print objects inside the dictionary. - elif [ -n "$array_found" ]; then - # Objects in arrays need an additional tab. - printf "\t\t\t\t$line\n" >> $tmpdictf - continue else - # Normal indentation. - printf "\t\t\t$line\n" >> $tmpdictf - continue + echo "$line" >> $tmpdictf fi done diff --git a/utils/sh/builddep_funcs.sh b/utils/sh/builddep_funcs.sh index 49581469629..be49a4bf982 100644 --- a/utils/sh/builddep_funcs.sh +++ b/utils/sh/builddep_funcs.sh @@ -147,7 +147,7 @@ install_dependencies_pkg() msg_normal "Required minimal deps for $(basename $pkg):" for i in ${installed_deps_list}; do ipkg=${i%-[0-9]*.*} - iversion="$($XBPS_PKGDB_CMD version $ipkg)" + iversion="$($XBPS_REGPKGDB_CMD version $ipkg)" echo " $ipkg >= ${i##[aA-zZ]*-}: found $ipkg-$iversion." done @@ -198,14 +198,14 @@ check_installed_pkg() local reqver="$2" local iver= - [ -z "$pkg" -o -z "$reqver" -o ! -r $XBPS_PKGDB_FPATH ] && return 1 + [ -z "$pkg" -o -z "$reqver" -o ! -r $XBPS_REGPKGDB_PATH ] && return 1 if [ "$pkgname" != "${pkg%-[0-9]*.*}" ]; then reset_tmpl_vars . $XBPS_TEMPLATESDIR/${pkg%-[0-9]*.*}.tmpl fi - iver="$($XBPS_PKGDB_CMD version $pkgname)" + iver="$($XBPS_REGPKGDB_CMD version $pkgname)" if [ -n "$iver" ]; then $XBPS_CMPVER_CMD $pkgname-$iver $pkgname-$reqver [ $? -eq 0 ] && return 0 diff --git a/utils/sh/pkgtarget_funcs.sh b/utils/sh/pkgtarget_funcs.sh index 598737e9b38..089e6d0ba0b 100644 --- a/utils/sh/pkgtarget_funcs.sh +++ b/utils/sh/pkgtarget_funcs.sh @@ -127,7 +127,7 @@ list_pkg_files() [ -z $pkg ] && msg_error "unexistent package, aborting." - ver=$($XBPS_PKGDB_CMD version $pkg) + ver=$($XBPS_REGPKGDB_CMD version $pkg) [ -z "$ver" ] && msg_error "$pkg is not installed." cat $XBPS_PKGMETADIR/$pkg/flist @@ -149,7 +149,7 @@ remove_pkg() . $XBPS_TEMPLATESDIR/$pkg.tmpl - ver=$($XBPS_PKGDB_CMD version $pkg) + ver=$($XBPS_REGPKGDB_CMD version $pkg) [ -z "$ver" ] && msg_error "$pkg is not installed." if [ ! -d "$XBPS_DESTDIR/$pkg-$ver" ]; then diff --git a/utils/sh/stow_funcs.sh b/utils/sh/stow_funcs.sh index d3e2aa2de04..6e1459a3227 100644 --- a/utils/sh/stow_funcs.sh +++ b/utils/sh/stow_funcs.sh @@ -58,7 +58,7 @@ stow_pkg() cp -ar ${i} $XBPS_MASTERDIR done - $XBPS_PKGDB_CMD register $pkgname $version "$short_desc" + $XBPS_REGPKGDB_CMD register $pkgname $version "$short_desc" [ $? -ne 0 ] && exit 1 # @@ -90,7 +90,7 @@ unstow_pkg() . $XBPS_TEMPLATESDIR/$pkg.tmpl fi - ver=$($XBPS_PKGDB_CMD version $pkg) + ver=$($XBPS_REGPKGDB_CMD version $pkg) if [ -z "$ver" ]; then msg_error "$pkg is not installed." fi @@ -124,6 +124,6 @@ unstow_pkg() # Remove metadata dir. rm -rf $XBPS_PKGMETADIR/$pkgname - $XBPS_PKGDB_CMD unregister $pkgname $ver + $XBPS_REGPKGDB_CMD unregister $pkgname $ver return $? } diff --git a/utils/sha256_digest.c b/utils/sha256_digest.c new file mode 100644 index 00000000000..317d1938b05 --- /dev/null +++ b/utils/sha256_digest.c @@ -0,0 +1,396 @@ +/* + * Written by Aaron D. Gifford + * + * Copyright 2000 Aaron D. Gifford. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sha256_digest.h" + +/*** SHA-256 Machine Architecture Definitions *****************/ + +/*** SHA-256 Various Length Definitions ***********************/ +/* NOTE: Most of these are in sha2.h */ +#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) + +/*** ENDIAN REVERSAL MACROS *******************************************/ +#ifndef WORDS_BIGENDIAN +#define REVERSE32(w,x) { \ + sha2_word32 tmp = (w); \ + tmp = (tmp >> 16) | (tmp << 16); \ + (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ +} +#define REVERSE64(w,x) { \ + sha2_word64 tmp = (w); \ + tmp = (tmp >> 32) | (tmp << 32); \ + tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ + ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ + (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ + ((tmp & 0x0000ffff0000ffffULL) << 16); \ +} +#endif /* WORDS_BIGENDIAN */ + +/* + * Macro for incrementally adding the unsigned 64-bit integer n to the + * unsigned 128-bit integer (represented using a two-element array of + * 64-bit words): + */ +#define ADDINC128(w,n) { \ + (w)[0] += (sha2_word64)(n); \ + if ((w)[0] < (n)) { \ + (w)[1]++; \ + } \ +} + +/*** THE SIX LOGICAL FUNCTIONS ****************************************/ +/* + * Bit shifting and rotation (used by the six SHA-XYZ logical functions: + * + * NOTE: The naming of R and S appears backwards here (R is a SHIFT and + * S is a ROTATION) because the SHA-256/384/512 description document + * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this + * same "backwards" definition. + */ +/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ +#define R(b,x) ((x) >> (b)) +/* 32-bit Rotate-right (used in SHA-256): */ +#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) + +/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ +#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +/* Four of six logical functions used in SHA-256: */ +#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) +#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) +#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) +#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) + +/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ +/* Hash constant words K for SHA-256: */ +const static sha2_word32 K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* Initial hash value H for SHA-256: */ +const static sha2_word32 sha256_initial_hash_value[8] = { + 0x6a09e667UL, + 0xbb67ae85UL, + 0x3c6ef372UL, + 0xa54ff53aUL, + 0x510e527fUL, + 0x9b05688cUL, + 0x1f83d9abUL, + 0x5be0cd19UL +}; + +/* Unrolled SHA-256 round macros: */ + +#ifndef WORDS_BIGENDIAN + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + REVERSE32(*data++, W256[j]); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + W256[j]; \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + + +#else /* WORDS__BIGENDIAN */ + +#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ + K256[j] + (W256[j] = *data++); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +#endif /* WORDS_BIGENDIAN */ + +#define ROUND256(a,b,c,d,e,f,g,h) \ + s0 = W256[(j+1)&0x0f]; \ + s0 = sigma0_256(s0); \ + s1 = W256[(j+14)&0x0f]; \ + s1 = sigma1_256(s1); \ + T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ + (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ + (d) += T1; \ + (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ + j++ + +static void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); +static void SHA256_Transform(SHA256_CTX*, const sha2_word32*); + +/*** SHA-256: *********************************************************/ +void SHA256_Init(SHA256_CTX* context) +{ + if (context == (SHA256_CTX*)0) { + return; + } + memcpy(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); + memset(context->buffer, 0, SHA256_BLOCK_LENGTH); + context->bitcount = 0; +} + +static void +SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) +{ + sha2_word32 a, b, c, d, e, f, g, h, s0, s1; + sha2_word32 T1, *W256; + int j; + + W256 = (sha2_word32*)context->buffer; + + /* Initialize registers with the prev. intermediate value */ + a = context->state[0]; + b = context->state[1]; + c = context->state[2]; + d = context->state[3]; + e = context->state[4]; + f = context->state[5]; + g = context->state[6]; + h = context->state[7]; + + j = 0; + do { + /* Rounds 0 to 15 (unrolled): */ + ROUND256_0_TO_15(a,b,c,d,e,f,g,h); + ROUND256_0_TO_15(h,a,b,c,d,e,f,g); + ROUND256_0_TO_15(g,h,a,b,c,d,e,f); + ROUND256_0_TO_15(f,g,h,a,b,c,d,e); + ROUND256_0_TO_15(e,f,g,h,a,b,c,d); + ROUND256_0_TO_15(d,e,f,g,h,a,b,c); + ROUND256_0_TO_15(c,d,e,f,g,h,a,b); + ROUND256_0_TO_15(b,c,d,e,f,g,h,a); + } while (j < 16); + + /* Now for the remaining rounds to 64: */ + do { + ROUND256(a,b,c,d,e,f,g,h); + ROUND256(h,a,b,c,d,e,f,g); + ROUND256(g,h,a,b,c,d,e,f); + ROUND256(f,g,h,a,b,c,d,e); + ROUND256(e,f,g,h,a,b,c,d); + ROUND256(d,e,f,g,h,a,b,c); + ROUND256(c,d,e,f,g,h,a,b); + ROUND256(b,c,d,e,f,g,h,a); + } while (j < 64); + + /* Compute the current intermediate hash value */ + context->state[0] += a; + context->state[1] += b; + context->state[2] += c; + context->state[3] += d; + context->state[4] += e; + context->state[5] += f; + context->state[6] += g; + context->state[7] += h; + + /* Clean up */ + a = b = c = d = e = f = g = h = T1 = 0; +} + +void +SHA256_Update(SHA256_CTX* context, const uint8_t *data, size_t len) +{ + unsigned int freespace, usedspace; + + if (len == 0) { + /* Calling with no data is valid - we do nothing */ + return; + } + + /* Sanity check: */ + assert(context != NULL && data != NULL); + + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; + if (usedspace > 0) { + /* Calculate how much free space is available in the buffer */ + freespace = SHA256_BLOCK_LENGTH - usedspace; + + if (len >= freespace) { + /* Fill the buffer completely and process it */ + memcpy(&context->buffer[usedspace], data, freespace); + context->bitcount += freespace << 3; + len -= freespace; + data += freespace; + SHA256_Transform(context, + (sha2_word32*)context->buffer); + } else { + /* The buffer is not yet full */ + memcpy(&context->buffer[usedspace], data, len); + context->bitcount += len << 3; + /* Clean up: */ + usedspace = freespace = 0; + return; + } + } + while (len >= SHA256_BLOCK_LENGTH) { + /* Process as many complete blocks as we can */ + SHA256_Transform(context, (const sha2_word32*)data); + context->bitcount += SHA256_BLOCK_LENGTH << 3; + len -= SHA256_BLOCK_LENGTH; + data += SHA256_BLOCK_LENGTH; + } + if (len > 0) { + /* There's left-overs, so save 'em */ + memcpy(context->buffer, data, len); + context->bitcount += len << 3; + } + /* Clean up: */ + usedspace = freespace = 0; +} + +static void +SHA256_Final(sha2_byte digest[], SHA256_CTX* context) +{ + sha2_word32 *d = (sha2_word32*)digest; + unsigned int usedspace; + + /* Sanity check: */ + assert(context != NULL); + + /* If no digest buffer is passed, we don't bother doing this: */ + if (digest != (sha2_byte*)0) { + usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; +#ifndef WORDS_BIGENDIAN + /* Convert FROM host byte order */ + REVERSE64(context->bitcount,context->bitcount); +#endif + if (usedspace > 0) { + /* Begin padding with a 1 bit: */ + context->buffer[usedspace++] = 0x80; + + if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { + /* Set-up for the last transform: */ + memset(&context->buffer[usedspace], 0, + SHA256_SHORT_BLOCK_LENGTH - usedspace); + } else { + if (usedspace < SHA256_BLOCK_LENGTH) { + memset(&context->buffer[usedspace], 0, + SHA256_BLOCK_LENGTH - usedspace); + } + /* Do second-to-last transform: */ + SHA256_Transform(context, + (sha2_word32*)context->buffer); + + /* And set-up for the last transform: */ + memset(context->buffer, 0, + SHA256_SHORT_BLOCK_LENGTH); + } + } else { + /* Set-up for the last transform: */ + memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); + + /* Begin padding with a 1 bit: */ + *context->buffer = 0x80; + } + /* Set the bit count: */ + *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = + context->bitcount; + + /* Final transform: */ + SHA256_Transform(context, (sha2_word32*)context->buffer); + +#ifndef WORDS_BIGENDIAN + { + /* Convert TO host byte order */ + int j; + for (j = 0; j < 8; j++) { + REVERSE32(context->state[j],context->state[j]); + *d++ = context->state[j]; + } + } +#else + memcpy(d, context->state, SHA256_DIGEST_LENGTH); +#endif + } + + /* Clean up state data: */ + memset(context, 0, sizeof(SHA256_CTX)); + usedspace = 0; +} + +/* + * Constant used by SHA256/384/512_End() functions for converting the + * digest to a readable hexadecimal character string: + */ +static const char sha2_hex_digits[] = "0123456789abcdef"; + +char * +SHA256_End(SHA256_CTX *ctx, uint8_t *buffer) +{ + uint8_t digest[SHA256_DIGEST_LENGTH], *d = digest; + uint8_t *ret; + int i; + + /* Sanity check: */ + assert(ctx != NULL); + + if ((ret = buffer) != NULL) { + SHA256_Final(digest, ctx); + + for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { + *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; + *buffer++ = sha2_hex_digits[*d & 0x0f]; + d++; + } + *buffer = (char) 0; + } else { + (void)memset(ctx, 0, sizeof(SHA256_CTX)); + } + (void)memset(digest, 0, SHA256_DIGEST_LENGTH); + return (char *)ret; +} diff --git a/utils/sha256_digest.h b/utils/sha256_digest.h new file mode 100644 index 00000000000..3da1231f081 --- /dev/null +++ b/utils/sha256_digest.h @@ -0,0 +1,55 @@ +/* + * Written by Aaron D. Gifford + * + * Copyright 2000 Aaron D. Gifford. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#ifndef _SHA2_DIGEST_H_ +#define _SHA2_DIGEST_H_ + +typedef uint8_t sha2_byte; /* Exactly 1 byte */ +typedef uint32_t sha2_word32; /* Exactly 4 bytes */ +typedef uint64_t sha2_word64; /* Exactly 8 bytes */ + +/*** SHA-256 Various Length Definitions ***********************/ +#define SHA256_BLOCK_LENGTH 64 +#define SHA256_DIGEST_LENGTH 32 +#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) + +/*** SHA-256 Context Structures *******************************/ +typedef struct _SHA256_CTX { + uint32_t state[8]; + uint64_t bitcount; + uint8_t buffer[SHA256_BLOCK_LENGTH]; +} SHA256_CTX; + +void SHA256_Init(SHA256_CTX *); +void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); +char *SHA256_End(SHA256_CTX*, uint8_t[SHA256_DIGEST_STRING_LENGTH]); + +#endif /* !_SHA2_DIGEST_H_ */ diff --git a/utils/xbps-digest.c b/utils/xbps-digest.c index 70f78145839..bdad91e9482 100644 --- a/utils/xbps-digest.c +++ b/utils/xbps-digest.c @@ -1,7 +1,6 @@ -/* - * Written by Aaron D. Gifford - * - * Copyright 2000 Aaron D. Gifford. All rights reserved. +/*- + * Copyright (c) 2008 Juan Romero Pardines. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -11,22 +10,17 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTOR(S) BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include @@ -41,376 +35,7 @@ #include #include -typedef uint8_t sha2_byte; /* Exactly 1 byte */ -typedef uint32_t sha2_word32; /* Exactly 4 bytes */ -typedef uint64_t sha2_word64; /* Exactly 8 bytes */ - -/*** SHA-256 Various Length Definitions ***********************/ -#define SHA256_BLOCK_LENGTH 64 -#define SHA256_DIGEST_LENGTH 32 -#define SHA256_DIGEST_STRING_LENGTH (SHA256_DIGEST_LENGTH * 2 + 1) - -/*** SHA-256 Context Structures *******************************/ -typedef struct _SHA256_CTX { - uint32_t state[8]; - uint64_t bitcount; - uint8_t buffer[SHA256_BLOCK_LENGTH]; -} SHA256_CTX; - -static void SHA256_Init(SHA256_CTX *); -static void SHA256_Update(SHA256_CTX*, const uint8_t*, size_t); -static void SHA256_Final(uint8_t[SHA256_DIGEST_LENGTH], SHA256_CTX*); -static char *SHA256_End(SHA256_CTX*, uint8_t[SHA256_DIGEST_STRING_LENGTH]); -static void SHA256_Transform(SHA256_CTX*, const sha2_word32*); - -/*** SHA-256 Machine Architecture Definitions *****************/ - -/*** SHA-256 Various Length Definitions ***********************/ -/* NOTE: Most of these are in sha2.h */ -#define SHA256_SHORT_BLOCK_LENGTH (SHA256_BLOCK_LENGTH - 8) - -/*** ENDIAN REVERSAL MACROS *******************************************/ -#ifndef WORDS_BIGENDIAN -#define REVERSE32(w,x) { \ - sha2_word32 tmp = (w); \ - tmp = (tmp >> 16) | (tmp << 16); \ - (x) = ((tmp & 0xff00ff00UL) >> 8) | ((tmp & 0x00ff00ffUL) << 8); \ -} -#define REVERSE64(w,x) { \ - sha2_word64 tmp = (w); \ - tmp = (tmp >> 32) | (tmp << 32); \ - tmp = ((tmp & 0xff00ff00ff00ff00ULL) >> 8) | \ - ((tmp & 0x00ff00ff00ff00ffULL) << 8); \ - (x) = ((tmp & 0xffff0000ffff0000ULL) >> 16) | \ - ((tmp & 0x0000ffff0000ffffULL) << 16); \ -} -#endif /* WORDS_BIGENDIAN */ - -/* - * Macro for incrementally adding the unsigned 64-bit integer n to the - * unsigned 128-bit integer (represented using a two-element array of - * 64-bit words): - */ -#define ADDINC128(w,n) { \ - (w)[0] += (sha2_word64)(n); \ - if ((w)[0] < (n)) { \ - (w)[1]++; \ - } \ -} - -/*** THE SIX LOGICAL FUNCTIONS ****************************************/ -/* - * Bit shifting and rotation (used by the six SHA-XYZ logical functions: - * - * NOTE: The naming of R and S appears backwards here (R is a SHIFT and - * S is a ROTATION) because the SHA-256/384/512 description document - * (see http://csrc.nist.gov/cryptval/shs/sha256-384-512.pdf) uses this - * same "backwards" definition. - */ -/* Shift-right (used in SHA-256, SHA-384, and SHA-512): */ -#define R(b,x) ((x) >> (b)) -/* 32-bit Rotate-right (used in SHA-256): */ -#define S32(b,x) (((x) >> (b)) | ((x) << (32 - (b)))) - -/* Two of six logical functions used in SHA-256, SHA-384, and SHA-512: */ -#define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) -#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -/* Four of six logical functions used in SHA-256: */ -#define Sigma0_256(x) (S32(2, (x)) ^ S32(13, (x)) ^ S32(22, (x))) -#define Sigma1_256(x) (S32(6, (x)) ^ S32(11, (x)) ^ S32(25, (x))) -#define sigma0_256(x) (S32(7, (x)) ^ S32(18, (x)) ^ R(3 , (x))) -#define sigma1_256(x) (S32(17, (x)) ^ S32(19, (x)) ^ R(10, (x))) - -/*** SHA-XYZ INITIAL HASH VALUES AND CONSTANTS ************************/ -/* Hash constant words K for SHA-256: */ -const static sha2_word32 K256[64] = { - 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, - 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, - 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, - 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, - 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, - 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, - 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, - 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, - 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, - 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, - 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, - 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, - 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, - 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, - 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, - 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL -}; - -/* Initial hash value H for SHA-256: */ -const static sha2_word32 sha256_initial_hash_value[8] = { - 0x6a09e667UL, - 0xbb67ae85UL, - 0x3c6ef372UL, - 0xa54ff53aUL, - 0x510e527fUL, - 0x9b05688cUL, - 0x1f83d9abUL, - 0x5be0cd19UL -}; - -/*** SHA-256: *********************************************************/ -static void SHA256_Init(SHA256_CTX* context) -{ - if (context == (SHA256_CTX*)0) { - return; - } - memcpy(context->state, sha256_initial_hash_value, SHA256_DIGEST_LENGTH); - memset(context->buffer, 0, SHA256_BLOCK_LENGTH); - context->bitcount = 0; -} - -/* Unrolled SHA-256 round macros: */ - -#ifndef WORDS_BIGENDIAN - -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - REVERSE32(*data++, W256[j]); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + W256[j]; \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - - -#else /* WORDS__BIGENDIAN */ - -#define ROUND256_0_TO_15(a,b,c,d,e,f,g,h) \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + \ - K256[j] + (W256[j] = *data++); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -#endif /* WORDS_BIGENDIAN */ - -#define ROUND256(a,b,c,d,e,f,g,h) \ - s0 = W256[(j+1)&0x0f]; \ - s0 = sigma0_256(s0); \ - s1 = W256[(j+14)&0x0f]; \ - s1 = sigma1_256(s1); \ - T1 = (h) + Sigma1_256(e) + Ch((e), (f), (g)) + K256[j] + \ - (W256[j&0x0f] += s1 + W256[(j+9)&0x0f] + s0); \ - (d) += T1; \ - (h) = T1 + Sigma0_256(a) + Maj((a), (b), (c)); \ - j++ - -static void -SHA256_Transform(SHA256_CTX* context, const sha2_word32* data) -{ - sha2_word32 a, b, c, d, e, f, g, h, s0, s1; - sha2_word32 T1, *W256; - int j; - - W256 = (sha2_word32*)context->buffer; - - /* Initialize registers with the prev. intermediate value */ - a = context->state[0]; - b = context->state[1]; - c = context->state[2]; - d = context->state[3]; - e = context->state[4]; - f = context->state[5]; - g = context->state[6]; - h = context->state[7]; - - j = 0; - do { - /* Rounds 0 to 15 (unrolled): */ - ROUND256_0_TO_15(a,b,c,d,e,f,g,h); - ROUND256_0_TO_15(h,a,b,c,d,e,f,g); - ROUND256_0_TO_15(g,h,a,b,c,d,e,f); - ROUND256_0_TO_15(f,g,h,a,b,c,d,e); - ROUND256_0_TO_15(e,f,g,h,a,b,c,d); - ROUND256_0_TO_15(d,e,f,g,h,a,b,c); - ROUND256_0_TO_15(c,d,e,f,g,h,a,b); - ROUND256_0_TO_15(b,c,d,e,f,g,h,a); - } while (j < 16); - - /* Now for the remaining rounds to 64: */ - do { - ROUND256(a,b,c,d,e,f,g,h); - ROUND256(h,a,b,c,d,e,f,g); - ROUND256(g,h,a,b,c,d,e,f); - ROUND256(f,g,h,a,b,c,d,e); - ROUND256(e,f,g,h,a,b,c,d); - ROUND256(d,e,f,g,h,a,b,c); - ROUND256(c,d,e,f,g,h,a,b); - ROUND256(b,c,d,e,f,g,h,a); - } while (j < 64); - - /* Compute the current intermediate hash value */ - context->state[0] += a; - context->state[1] += b; - context->state[2] += c; - context->state[3] += d; - context->state[4] += e; - context->state[5] += f; - context->state[6] += g; - context->state[7] += h; - - /* Clean up */ - a = b = c = d = e = f = g = h = T1 = 0; -} - -static void -SHA256_Update(SHA256_CTX* context, const uint8_t *data, size_t len) -{ - unsigned int freespace, usedspace; - - if (len == 0) { - /* Calling with no data is valid - we do nothing */ - return; - } - - /* Sanity check: */ - assert(context != NULL && data != NULL); - - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; - if (usedspace > 0) { - /* Calculate how much free space is available in the buffer */ - freespace = SHA256_BLOCK_LENGTH - usedspace; - - if (len >= freespace) { - /* Fill the buffer completely and process it */ - memcpy(&context->buffer[usedspace], data, freespace); - context->bitcount += freespace << 3; - len -= freespace; - data += freespace; - SHA256_Transform(context, - (sha2_word32*)context->buffer); - } else { - /* The buffer is not yet full */ - memcpy(&context->buffer[usedspace], data, len); - context->bitcount += len << 3; - /* Clean up: */ - usedspace = freespace = 0; - return; - } - } - while (len >= SHA256_BLOCK_LENGTH) { - /* Process as many complete blocks as we can */ - SHA256_Transform(context, (const sha2_word32*)data); - context->bitcount += SHA256_BLOCK_LENGTH << 3; - len -= SHA256_BLOCK_LENGTH; - data += SHA256_BLOCK_LENGTH; - } - if (len > 0) { - /* There's left-overs, so save 'em */ - memcpy(context->buffer, data, len); - context->bitcount += len << 3; - } - /* Clean up: */ - usedspace = freespace = 0; -} - -static void -SHA256_Final(sha2_byte digest[], SHA256_CTX* context) -{ - sha2_word32 *d = (sha2_word32*)digest; - unsigned int usedspace; - - /* Sanity check: */ - assert(context != NULL); - - /* If no digest buffer is passed, we don't bother doing this: */ - if (digest != (sha2_byte*)0) { - usedspace = (context->bitcount >> 3) % SHA256_BLOCK_LENGTH; -#ifndef WORDS_BIGENDIAN - /* Convert FROM host byte order */ - REVERSE64(context->bitcount,context->bitcount); -#endif - if (usedspace > 0) { - /* Begin padding with a 1 bit: */ - context->buffer[usedspace++] = 0x80; - - if (usedspace <= SHA256_SHORT_BLOCK_LENGTH) { - /* Set-up for the last transform: */ - memset(&context->buffer[usedspace], 0, - SHA256_SHORT_BLOCK_LENGTH - usedspace); - } else { - if (usedspace < SHA256_BLOCK_LENGTH) { - memset(&context->buffer[usedspace], 0, - SHA256_BLOCK_LENGTH - usedspace); - } - /* Do second-to-last transform: */ - SHA256_Transform(context, - (sha2_word32*)context->buffer); - - /* And set-up for the last transform: */ - memset(context->buffer, 0, - SHA256_SHORT_BLOCK_LENGTH); - } - } else { - /* Set-up for the last transform: */ - memset(context->buffer, 0, SHA256_SHORT_BLOCK_LENGTH); - - /* Begin padding with a 1 bit: */ - *context->buffer = 0x80; - } - /* Set the bit count: */ - *(sha2_word64*)&context->buffer[SHA256_SHORT_BLOCK_LENGTH] = - context->bitcount; - - /* Final transform: */ - SHA256_Transform(context, (sha2_word32*)context->buffer); - -#ifndef WORDS_BIGENDIAN - { - /* Convert TO host byte order */ - int j; - for (j = 0; j < 8; j++) { - REVERSE32(context->state[j],context->state[j]); - *d++ = context->state[j]; - } - } -#else - memcpy(d, context->state, SHA256_DIGEST_LENGTH); -#endif - } - - /* Clean up state data: */ - memset(context, 0, sizeof(SHA256_CTX)); - usedspace = 0; -} - -/* - * Constant used by SHA256/384/512_End() functions for converting the - * digest to a readable hexadecimal character string: - */ -static const char sha2_hex_digits[] = "0123456789abcdef"; - -static char * -SHA256_End(SHA256_CTX *ctx, uint8_t *buffer) -{ - uint8_t digest[SHA256_DIGEST_LENGTH], *d = digest; - uint8_t *ret; - int i; - - /* Sanity check: */ - assert(ctx != NULL); - - if ((ret = buffer) != NULL) { - SHA256_Final(digest, ctx); - - for (i = 0; i < SHA256_DIGEST_LENGTH; i++) { - *buffer++ = sha2_hex_digits[(*d & 0xf0) >> 4]; - *buffer++ = sha2_hex_digits[*d & 0x0f]; - d++; - } - *buffer = (char) 0; - } else { - (void)memset(ctx, 0, sizeof(SHA256_CTX)); - } - (void)memset(digest, 0, SHA256_DIGEST_LENGTH); - return (char *)ret; -} +#include "xbps_api.h" static void usage(void) @@ -439,7 +64,8 @@ main(int argc, char **argv) digest = malloc(SHA256_DIGEST_LENGTH * 2 + 1); if (digest == NULL) { - printf("xbps-digest: malloc failed (%s)\n", strerror(errno)); + printf("xbps-digest: malloc failed (%s)\n", + strerror(errno)); exit(1); } diff --git a/utils/xbps-pkgdb.c b/utils/xbps-pkgdb.c index 193d2e2252c..7ec6b8a08bc 100644 --- a/utils/xbps-pkgdb.c +++ b/utils/xbps-pkgdb.c @@ -30,9 +30,7 @@ #include #include -#include - -#define _XBPS_PKGDB_DEFPATH "/var/cache/xbps/pkgdb.plist" +#include "xbps_api.h" typedef struct pkg_data { const char *pkgname; @@ -40,101 +38,10 @@ typedef struct pkg_data { const char *short_desc; } pkg_data_t; -static void usage(void); -static void add_array_to_dict(prop_dictionary_t, prop_array_t, const char *); -static void add_obj_to_array(prop_array_t, prop_object_t); static prop_dictionary_t make_dict_from_pkg(pkg_data_t *); -static prop_dictionary_t find_pkg_in_dict(prop_dictionary_t, const char *); static void register_pkg(prop_dictionary_t, pkg_data_t *, const char *); static void unregister_pkg(prop_dictionary_t, const char *, const char *); static void write_plist_file(prop_dictionary_t, const char *); -static void list_pkgs_in_dict(prop_dictionary_t); -static prop_dictionary_t get_dict_from_dbfile(const char *); - -static void -usage(void) -{ - printf("usage: xbps-pkgdb [args]\n"); - printf("\n"); - printf(" Available actions:\n"); - printf(" list, register, unregister, version\n"); - printf(" Action arguments:\n"); - printf(" list\t[none]\n"); - printf(" register\t[ ]\n"); - printf(" unregister\t[ ]\n"); - printf(" version\t[]\n"); - printf(" Environment:\n"); - printf(" XBPS_PKGDB_FPATH\tPath to xbps pkgdb plist file\n"); - printf("\n"); - printf(" Examples:\n"); - printf(" $ xbps-pkgdb list\n"); - printf(" $ xbps-pkgdb register pkgname 2.0 \"A short description\"\n"); - printf(" $ xbps-pkgdb unregister pkgname 2.0\n"); - printf(" $ xbps-pkgdb version pkgname\n"); - exit(1); -} - -static prop_dictionary_t -find_pkg_in_dict(prop_dictionary_t dict, const char *pkgname) -{ - prop_array_t array; - prop_object_iterator_t iter; - prop_object_t obj; - const char *dpkgn; - - if (dict == NULL || pkgname == NULL) - return NULL; - - array = prop_dictionary_get(dict, "packages_installed"); - if (array == NULL || prop_object_type(array) != PROP_TYPE_ARRAY) - return NULL; - - iter = prop_array_iterator(array); - if (iter == NULL) - return NULL; - - while ((obj = prop_object_iterator_next(iter))) { - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &dpkgn); - if (strcmp(dpkgn, pkgname) == 0) - break; - } - prop_object_iterator_release(iter); - - return obj; -} - -static void -add_obj_to_array(prop_array_t array, prop_object_t obj) -{ - if (array == NULL || obj == NULL) { - printf("%s: NULL array/obj\n", __func__); - exit(1); - } - - if (!prop_array_add(array, obj)) { - prop_object_release(array); - printf("%s: couldn't add obj into array: %s\n", __func__, - strerror(errno)); - exit(1); - } - prop_object_release(obj); -} - -static void -add_array_to_dict(prop_dictionary_t dict, prop_array_t array, const char *key) -{ - if (dict == NULL || array == NULL || key == NULL) { - printf("%s: NULL dict/array/key\n", __func__); - exit(1); - } - - if (!prop_dictionary_set(dict, key, array)) { - printf("%s: couldn't add array (%s): %s\n", - __func__, key, strerror(errno)); - exit(1); - } - prop_object_release(array); -} static prop_dictionary_t make_dict_from_pkg(pkg_data_t *pkg) @@ -179,7 +86,11 @@ register_pkg(prop_dictionary_t dict, pkg_data_t *pkg, const char *dbfile) exit(1); } - add_obj_to_array(array, pkgdict); + if (!xbps_add_obj_to_array(array, pkgdict)) { + printf("ERROR: couldn't register package in database!\n"); + exit(1); + } + write_plist_file(dict, dbfile); } @@ -226,7 +137,12 @@ unregister_pkg(prop_dictionary_t dict, const char *pkgname, const char *dbfile) } prop_array_remove(array, i); - add_array_to_dict(dict, array, "packages_installed"); + if (!xbps_add_array_to_dict(dict, array, "packages_installed")) { + printf("=> ERROR: couldn't unregister %s from database\n", + pkgname); + exit(1); + } + write_plist_file(dict, dbfile); } @@ -246,49 +162,26 @@ write_plist_file(prop_dictionary_t dict, const char *file) } static void -list_pkgs_in_dict(prop_dictionary_t dict) +usage(void) { - prop_array_t array; - prop_object_t obj; - prop_object_iterator_t iter; - const char *pkgname, *version, *short_desc; - - if (dict == NULL) - exit(1); - - array = prop_dictionary_get(dict, "packages_installed"); - if (array == NULL || prop_object_type(array) != PROP_TYPE_ARRAY) { - printf("%s: NULL or incorrect array type\n", __func__); - exit(1); - } - - iter = prop_array_iterator(array); - if (iter == NULL) { - printf("%s: NULL iter\n", __func__); - exit(1); - } - - while ((obj = prop_object_iterator_next(iter))) { - prop_dictionary_get_cstring_nocopy(obj, "pkgname", &pkgname); - prop_dictionary_get_cstring_nocopy(obj, "version", &version); - prop_dictionary_get_cstring_nocopy(obj, "short_desc", &short_desc); - if (pkgname && version && short_desc) - printf("%s (%s)\t%s\n", pkgname, version, short_desc); - } - prop_object_iterator_release(iter); -} - -static prop_dictionary_t -get_dict_from_dbfile(const char *file) -{ - prop_dictionary_t dict; - - dict = prop_dictionary_internalize_from_file(file); - if (dict == NULL) { - perror("=> ERROR: couldn't find database file"); - exit(1); - } - return dict; + printf("usage: xbps-pkgdb [args]\n\n" + " Available actions:\n" + " list, register, sanitize-plist, unregister, version\n" + " Action arguments:\n" + " list\t[none]\n" + " register\t[ ]\n" + " sanitize-plist\t[]\n" + " unregister\t[ ]\n" + " version\t[]\n" + " Environment:\n" + " XBPS_REGPKGDB_PATH\tPath to xbps pkgdb plist file\n\n" + " Examples:\n" + " $ xbps-pkgdb list\n" + " $ xbps-pkgdb register pkgname 2.0 \"A short description\"\n" + " $ xbps-pkgdb sanitize-plist /blah/foo.plist\n" + " $ xbps-pkgdb unregister pkgname 2.0\n" + " $ xbps-pkgdb version pkgname\n"); + exit(1); } int @@ -304,15 +197,15 @@ main(int argc, char **argv) if (argc < 2) usage(); - if ((dbfileenv = getenv("XBPS_PKGDB_FPATH")) != NULL) { - /* Use path as defined by XBPS_PKGDB_FPATH env var */ + if ((dbfileenv = getenv("XBPS_REGPKGDB_PATH")) != NULL) { + /* Use path as defined by XBPS_REGPKGDB_PATH env var */ tmppath = strncpy(dbfile, dbfileenv, sizeof(dbfile)); if (sizeof(*tmppath) >= sizeof(dbfile)) exit(1); } else { /* Use default path */ tmppath = - strncpy(dbfile, _XBPS_PKGDB_DEFPATH, sizeof(dbfile)); + strncpy(dbfile, XBPS_REGPKGDB_DEFPATH, sizeof(dbfile)); if (sizeof(*tmppath) >= sizeof(dbfile)) exit(1); } @@ -342,11 +235,18 @@ main(int argc, char **argv) /* Add pkg dictionary into array. */ dbarray = prop_array_create(); - add_obj_to_array(dbarray, pkgdict); + if (!xbps_add_obj_to_array(dbarray, pkgdict)) { + printf("=> ERROR: couldn't register pkg\n"); + exit(1); + } /* Add array into main dictionary. */ dbdict = prop_dictionary_create(); - add_array_to_dict(dbdict, dbarray, "packages_installed"); + if (!xbps_add_array_to_dict(dbdict, dbarray, + "packages_installed")) { + printf("=> ERROR: couldn't register pkg\n"); + exit(1); + } /* Write main dictionary to file. */ write_plist_file(dbdict, dbfile); @@ -357,7 +257,8 @@ main(int argc, char **argv) prop_object_release(dbdict); } else { /* Check if pkg is already registered. */ - pkgdict = find_pkg_in_dict(dbdict, argv[2]); + pkgdict = xbps_find_pkg_in_dict(dbdict, + "packages_installed", argv[2]); if (pkgdict != NULL) { printf("%s=> Package %s-%s already registered.\n", in_chroot ? "[chroot] " : "", @@ -379,7 +280,8 @@ main(int argc, char **argv) if (argc != 4) usage(); - unregister_pkg(get_dict_from_dbfile(dbfile), argv[2], dbfile); + unregister_pkg(prop_dictionary_internalize_from_file(dbfile), + argv[2], dbfile); printf("%s=> %s-%s unregistered successfully.\n", in_chroot ? "[chroot] " : "", argv[2], argv[3]); @@ -389,20 +291,40 @@ main(int argc, char **argv) if (argc != 2) usage(); - list_pkgs_in_dict(get_dict_from_dbfile(dbfile)); + dbdict = prop_dictionary_internalize_from_file(dbfile); + xbps_list_pkgs_in_dict(dbdict, "packages_installed"); } else if (strcmp(argv[1], "version") == 0) { /* Prints version of an installed package */ if (argc != 3) usage(); - pkgdict = find_pkg_in_dict(get_dict_from_dbfile(dbfile), argv[2]); + pkgdict = xbps_find_pkg_in_dict( + prop_dictionary_internalize_from_file(dbfile), + "packages_installed", argv[2]); if (pkgdict == NULL) exit(1); - if (!prop_dictionary_get_cstring_nocopy(pkgdict, "version", &version)) + if (!prop_dictionary_get_cstring_nocopy(pkgdict, "version", + &version)) exit(1); printf("%s\n", version); + } else if (strcmp(argv[1], "sanitize-plist") == 0) { + /* Sanitize a plist file (indent the file properly) */ + if (argc != 3) + usage(); + + dbdict = prop_dictionary_internalize_from_file(argv[2]); + if (dbdict == NULL) { + printf("=> ERROR: couldn't sanitize %s plist file\n", + argv[2]); + exit(1); + } + if (!prop_dictionary_externalize_to_file(dbdict, argv[2])) { + printf("=> ERROR: couldn't write new plist file\n"); + exit(1); + } + } else { usage(); } diff --git a/utils/xbps_api.h b/utils/xbps_api.h new file mode 100644 index 00000000000..cdb07a7d493 --- /dev/null +++ b/utils/xbps_api.h @@ -0,0 +1,46 @@ +/*- + * Copyright (c) 2008 Juan Romero Pardines. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _XBPS_API_H_ +#define _XBPS_API_H_ + +#include +#include + +#include + +/* Filename of the package index plist for a repository. */ +#define XBPS_PKGINDEX "pkg-index.plist" + +/* Default PATH for the plist file to register installed packages. */ +#define XBPS_REGPKGDB_DEFPATH "/var/cache/xbps/regpkgdb.plist" + +/* API to handle plist files */ +#include "plist_utils.h" + +/* SHA256 implementation */ +#include "sha256_digest.h" + +#endif /* !_XBPS_API_H_ */ diff --git a/xbps-src.sh b/xbps-src.sh index b4b68aabce2..49f5e6499ec 100755 --- a/xbps-src.sh +++ b/xbps-src.sh @@ -99,12 +99,12 @@ set_defvars() : ${XBPS_TEMPLATESDIR:=$XBPS_DISTRIBUTIONDIR/templates} : ${XBPS_HELPERSDIR:=$XBPS_TEMPLATESDIR/helpers} : ${XBPS_CACHEDIR:=$XBPS_MASTERDIR/var/cache/xbps} - : ${XBPS_PKGDB_FPATH:=$XBPS_CACHEDIR/pkgdb.plist} + : ${XBPS_REGPKGDB_PATH:=$XBPS_CACHEDIR/regpkgdb.plist} : ${XBPS_PKGMETADIR:=$XBPS_CACHEDIR/metadata} : ${XBPS_UTILSDIR:=$XBPS_DISTRIBUTIONDIR/utils} : ${XBPS_SHUTILSDIR:=$XBPS_UTILSDIR/sh} : ${XBPS_DIGEST_CMD:=$XBPS_UTILSDIR/xbps-digest} - : ${XBPS_PKGDB_CMD:=$XBPS_UTILSDIR/xbps-pkgdb} + : ${XBPS_REGPKGDB_CMD:=$XBPS_UTILSDIR/xbps-pkgdb} : ${XBPS_CMPVER_CMD:=$XBPS_UTILSDIR/xbps-cmpver} local DDIRS="XBPS_TEMPLATESDIR XBPS_HELPERSDIR XBPS_UTILSDIR \ @@ -114,7 +114,8 @@ set_defvars() [ ! -d "$val" ] && msg_error "cannot find $i, aborting." done - XBPS_PKGDB_CMD="env XBPS_PKGDB_FPATH=$XBPS_PKGDB_FPATH $XBPS_PKGDB_CMD" + XBPS_REGPKGDB_CMD="env XBPS_REGPKGDB_PATH=$XBPS_REGPKGDB_PATH \ + $XBPS_REGPKGDB_CMD" } # @@ -230,7 +231,7 @@ build-pkg) . $XBPS_SHUTILSDIR/binpkg.sh . $XBPS_SHUTILSDIR/tmpl_funcs.sh if [ "$2" = "all" ]; then - for f in $($XBPS_PKGDB_CMD list|awk '{print $1}'); do + for f in $($XBPS_REGPKGDB_CMD list|awk '{print $1}'); do setup_tmpl $f xbps_make_binpkg reset_tmpl_vars @@ -272,7 +273,7 @@ install|install-destdir) ;; list|listfiles) if [ "$target" = "list" ]; then - $XBPS_PKGDB_CMD list + $XBPS_REGPKGDB_CMD list exit $? fi . $XBPS_SHUTILSDIR/pkgtarget_funcs.sh