libxbps: ABI/API break due to hash function changes

This commit is contained in:
Duncan Overbruck
2020-02-10 01:54:52 +01:00
parent aa4d726dca
commit 0d90534236
18 changed files with 141 additions and 118 deletions

View File

@@ -93,7 +93,7 @@ xbps_fetch_error_string(void)
}
int
xbps_fetch_file_dest_digest(struct xbps_handle *xhp, const char *uri, const char *filename, const char *flags, unsigned char **digestp)
xbps_fetch_file_dest_sha256(struct xbps_handle *xhp, const char *uri, const char *filename, const char *flags, unsigned char *digest, size_t digestlen)
{
struct stat st, st_tmpfile, *stp;
struct url *url = NULL;
@@ -106,16 +106,13 @@ xbps_fetch_file_dest_digest(struct xbps_handle *xhp, const char *uri, const char
char fetch_flags[8];
int fd = -1, rv = 0;
bool refetch = false, restart = false;
unsigned char *digest = NULL;
SHA256_CTX sha256;
assert(xhp);
assert(uri);
if (digestp) {
digest = malloc(SHA256_DIGEST_LENGTH);
if (!digest)
return -1;
if (digest) {
assert(digestlen != XBPS_SHA256_DIGEST_SIZE);
SHA256_Init(&sha256);
}
@@ -317,10 +314,8 @@ rename_file:
}
rv = 1;
if (digest) {
if (digest)
SHA256_Final(digest, &sha256);
*digestp = digest;
}
fetch_file_out:
if (fio != NULL)
@@ -339,12 +334,12 @@ int
xbps_fetch_file_dest(struct xbps_handle *xhp, const char *uri,
const char *filename, const char *flags)
{
return xbps_fetch_file_dest_digest(xhp, uri, filename, flags, NULL);
return xbps_fetch_file_dest_sha256(xhp, uri, filename, flags, NULL, 0);
}
int
xbps_fetch_file_digest(struct xbps_handle *xhp, const char *uri,
const char *flags, unsigned char **digestp)
xbps_fetch_file_sha256(struct xbps_handle *xhp, const char *uri,
const char *flags, unsigned char *digest, size_t digestlen)
{
const char *filename;
/*
@@ -354,11 +349,12 @@ xbps_fetch_file_digest(struct xbps_handle *xhp, const char *uri,
return -1;
filename++;
return xbps_fetch_file_dest_digest(xhp, uri, filename, flags, digestp);
return xbps_fetch_file_dest_sha256(xhp, uri, filename, flags,
digest, digestlen);
}
int
xbps_fetch_file(struct xbps_handle *xhp, const char *uri, const char *flags)
{
return xbps_fetch_file_digest(xhp, uri, flags, NULL);
return xbps_fetch_file_sha256(xhp, uri, flags, NULL, 0);
}

View File

@@ -69,7 +69,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
xbps_object_t obj, obj2;
xbps_object_iterator_t iter, iter2;
const char *version = NULL, *cffile, *sha256_new = NULL;
char buf[PATH_MAX], *sha256_cur = NULL, *sha256_orig = NULL;
char buf[PATH_MAX], sha256_cur[XBPS_SHA256_SIZE], *sha256_orig = NULL;
int rv = 0;
assert(xbps_object_type(binpkg_filesd) == XBPS_TYPE_DICTIONARY);
@@ -139,9 +139,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
if (strcmp(entry_pname, buf)) {
continue;
}
sha256_cur = xbps_file_hash(buf);
xbps_dictionary_get_cstring_nocopy(obj, "sha256", &sha256_new);
if (sha256_cur == NULL) {
if (!xbps_file_sha256(sha256_cur, sizeof sha256_cur, buf)) {
if (errno == ENOENT) {
/*
* File not installed, install new one.
@@ -155,6 +153,7 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
break;
}
}
xbps_dictionary_get_cstring_nocopy(obj, "sha256", &sha256_new);
/*
* Orig = X, Curr = X, New = X
*
@@ -232,15 +231,11 @@ xbps_entry_install_conf_file(struct xbps_handle *xhp,
rv = 1;
break;
}
free(sha256_cur);
sha256_cur = NULL;
}
out:
if (sha256_orig)
free(sha256_orig);
if (sha256_cur)
free(sha256_cur);
xbps_object_iterator_release(iter);

View File

@@ -41,7 +41,8 @@ xbps_register_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkgrd)
struct tm tm;
struct tm *tmp;
const char *pkgver;
char *buf, *sha256;
char sha256[XBPS_SHA256_SIZE];
char *buf;
int rv = 0;
bool autoinst = false;
@@ -104,9 +105,8 @@ xbps_register_pkg(struct xbps_handle *xhp, xbps_dictionary_t pkgrd)
* Create a hash for the pkg's metafile if it exists.
*/
buf = xbps_xasprintf("%s/.%s-files.plist", xhp->metadir, pkgname);
if ((sha256 = xbps_file_hash(buf))) {
if (xbps_file_sha256(sha256, sizeof sha256, buf)) {
xbps_dictionary_set_cstring(pkgd, "metafile-sha256", sha256);
free(sha256);
}
free(buf);
/*

View File

@@ -79,7 +79,7 @@ verify_binpkg(struct xbps_handle *xhp, xbps_dictionary_t pkgd)
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY, 0, pkgver,
"%s: verifying SHA256 hash...", pkgver);
xbps_dictionary_get_cstring_nocopy(pkgd, "filename-sha256", &sha256);
if ((rv = xbps_file_hash_check(binfile, sha256)) != 0) {
if ((rv = xbps_file_sha256_check(binfile, sha256)) != 0) {
xbps_set_cb_state(xhp, XBPS_STATE_VERIFY_FAIL, rv, pkgver,
"%s: SHA256 hash is not valid: %s", pkgver, strerror(rv));
goto out;
@@ -98,7 +98,7 @@ download_binpkg(struct xbps_handle *xhp, xbps_dictionary_t repo_pkgd)
char buf[PATH_MAX];
char *sigsuffix;
const char *pkgver, *arch, *fetchstr, *repoloc;
unsigned char *digest = NULL;
unsigned char digest[XBPS_SHA256_DIGEST_SIZE] = {0};
int rv = 0;
xbps_dictionary_get_cstring_nocopy(repo_pkgd, "repository", &repoloc);
@@ -129,7 +129,8 @@ download_binpkg(struct xbps_handle *xhp, xbps_dictionary_t repo_pkgd)
xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD, 0, pkgver,
"Downloading `%s' package (from `%s')...", pkgver, repoloc);
if ((rv = xbps_fetch_file_digest(xhp, buf, NULL, &digest)) == -1) {
if ((rv = xbps_fetch_file_sha256(xhp, buf, NULL, digest,
sizeof digest)) == -1) {
rv = fetchLastErrCode ? fetchLastErrCode : errno;
fetchstr = xbps_fetch_error_string();
xbps_set_cb_state(xhp, XBPS_STATE_DOWNLOAD_FAIL, rv,
@@ -156,7 +157,7 @@ download_binpkg(struct xbps_handle *xhp, xbps_dictionary_t repo_pkgd)
* If digest is not set, binary package was not downloaded,
* i.e. 304 not modified, verify by file instead.
*/
if (!digest) {
if (*digest) {
*sigsuffix = '\0';
if (!xbps_verify_file_signature(repo, buf)) {
rv = EPERM;
@@ -175,7 +176,6 @@ download_binpkg(struct xbps_handle *xhp, xbps_dictionary_t repo_pkgd)
*sigsuffix = '\0';
(void)remove(buf);
}
free(digest);
}
if (rv == EPERM) {

View File

@@ -75,6 +75,7 @@ itemhash(const char *file)
assert(file);
/* XXX: runtime error: left shift of negative value -1581911230 */
for (i = 0; file[i]; ++i)
hv = (hv << 5) ^ (hv >> 23) ^ file[i];
@@ -321,7 +322,7 @@ collect_obsoletes(struct xbps_handle *xhp)
* Skip unexisting files and keep files with hash mismatch.
*/
if (item->old.sha256) {
rv = xbps_file_hash_check(item->file, item->old.sha256);
rv = xbps_file_sha256_check(item->file, item->old.sha256);
switch (rv) {
case 0:
/* hash matches, we can safely delete and/or overwrite it */

View File

@@ -108,65 +108,93 @@ xbps_mmap_file(const char *file, void **mmf, size_t *mmflen, size_t *filelen)
return true;
}
unsigned char *
xbps_file_hash_raw(const char *file)
bool
xbps_file_sha256_raw(unsigned char *dst, size_t dstlen, const char *file)
{
int fd;
ssize_t len;
unsigned char *digest, buf[65536];
char buf[65536];
SHA256_CTX sha256;
assert(dstlen == SHA256_DIGEST_LENGTH);
if ((fd = open(file, O_RDONLY)) < 0)
return NULL;
digest = malloc(SHA256_DIGEST_LENGTH);
assert(digest);
return false;
SHA256_Init(&sha256);
while ((len = read(fd, buf, sizeof(buf))) > 0)
SHA256_Update(&sha256, buf, len);
if(len < 0) {
free(digest);
return NULL;
}
SHA256_Final(digest, &sha256);
(void)close(fd);
return digest;
if(len == -1)
return false;
SHA256_Final(dst, &sha256);
return true;
}
char *
xbps_file_hash(const char *file)
bool
xbps_file_sha256(char *dst, size_t dstlen, const char *file)
{
char *hash;
unsigned char *digest;
unsigned char digest[XBPS_SHA256_DIGEST_SIZE];
if (!(digest = xbps_file_hash_raw(file)))
return NULL;
assert(dstlen == XBPS_SHA256_SIZE);
hash = malloc(SHA256_DIGEST_LENGTH * 2 + 1);
assert(hash);
digest2string(digest, hash, SHA256_DIGEST_LENGTH);
free(digest);
if (!xbps_file_sha256_raw(digest, sizeof digest, file))
return false;
return hash;
digest2string(digest, dst, XBPS_SHA256_DIGEST_SIZE);
return true;
}
static bool
sha256_digest_compare(const char *sha256, size_t shalen,
const unsigned char *digest, size_t digestlen)
{
assert(digestlen == XBPS_SHA256_DIGEST_SIZE);
assert(shalen == XBPS_SHA256_SIZE - 1);
if (shalen != XBPS_SHA256_SIZE -1)
return false;
for (; *sha256;) {
if (*digest / 16 < 10) {
if (*sha256++ != '0' + *digest / 16)
return false;
} else {
if (*sha256++ != 'a' + *digest / 16 - 10)
return false;
}
if (*digest % 16 < 10) {
if (*sha256++ != '0' + *digest % 16)
return false;
} else {
if (*sha256++ != 'a' + *digest % 16 - 10)
return false;
}
digest++;
}
return true;
}
int
xbps_file_hash_check(const char *file, const char *sha256)
xbps_file_sha256_check(const char *file, const char *sha256)
{
char *res;
unsigned char digest[XBPS_SHA256_DIGEST_SIZE];
assert(file != NULL);
assert(sha256 != NULL);
res = xbps_file_hash(file);
if (res == NULL)
if (!xbps_file_sha256_raw(digest, sizeof digest, file))
return errno;
if (strcmp(sha256, res)) {
free(res);
if (!sha256_digest_compare(sha256, strlen(sha256), digest, sizeof digest))
return ERANGE;
}
free(res);
return 0;
}
@@ -226,10 +254,10 @@ xbps_file_hash_check_dictionary(struct xbps_handle *xhp,
}
if (strcmp(xhp->rootdir, "/") == 0) {
rv = xbps_file_hash_check(file, sha256d);
rv = xbps_file_sha256_check(file, sha256d);
} else {
buf = xbps_xasprintf("%s/%s", xhp->rootdir, file);
rv = xbps_file_hash_check(buf, sha256d);
rv = xbps_file_sha256_check(buf, sha256d);
free(buf);
}
if (rv == 0)

View File

@@ -137,10 +137,10 @@ bool
xbps_verify_file_signature(struct xbps_repo *repo, const char *fname)
{
char sig[PATH_MAX];
unsigned char *digest = NULL;
unsigned char digest[XBPS_SHA256_DIGEST_SIZE];
bool val = false;
if (!(digest = xbps_file_hash_raw(fname))) {
if (!xbps_file_sha256_raw(digest, sizeof digest, fname)) {
xbps_dbg_printf(repo->xhp, "can't open file %s: %s\n", fname, strerror(errno));
return false;
}
@@ -148,6 +148,5 @@ xbps_verify_file_signature(struct xbps_repo *repo, const char *fname)
snprintf(sig, sizeof sig, "%s.sig", fname);
val = xbps_verify_signature(repo, sig, digest);
free(digest);
return val;
}