From 6941aac4c6379bebe7ee0a759f4a4b6df03c3984 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timo=20Ter=C3=A4s?= Date: Mon, 25 Oct 2021 17:14:00 +0300 Subject: [PATCH] db, audit: support sha256-160 hashes for v3 pkg compat --- src/apk_crypto.h | 6 ++++-- src/apk_database.h | 8 ++++++++ src/apk_package.h | 1 + src/app_audit.c | 2 +- src/crypto_openssl.c | 12 +++++++----- src/database.c | 17 ++++++++++++----- 6 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/apk_crypto.h b/src/apk_crypto.h index 43b4bd2..0330694 100644 --- a/src/apk_crypto.h +++ b/src/apk_crypto.h @@ -27,6 +27,7 @@ struct apk_digest_ctx { #define APK_DIGEST_SHA1 0x02 #define APK_DIGEST_SHA256 0x03 #define APK_DIGEST_SHA512 0x04 +#define APK_DIGEST_SHA256_160 0x05 #define APK_DIGEST_MAX_LENGTH 64 // longest is SHA512 @@ -45,6 +46,7 @@ static inline const EVP_MD *apk_digest_alg_to_evp(uint8_t alg) { case APK_DIGEST_NONE: return EVP_md_null(); case APK_DIGEST_MD5: return EVP_md5(); case APK_DIGEST_SHA1: return EVP_sha1(); + case APK_DIGEST_SHA256_160: case APK_DIGEST_SHA256: return EVP_sha256(); case APK_DIGEST_SHA512: return EVP_sha512(); default: @@ -77,7 +79,7 @@ static inline int apk_digest_calc(struct apk_digest *d, uint8_t alg, const void if (EVP_Digest(ptr, sz, d->data, &md_sz, apk_digest_alg_to_evp(alg), 0) != 1) return -APKE_CRYPTO_ERROR; d->alg = alg; - d->len = md_sz; + d->len = apk_digest_alg_len(alg); return 0; } @@ -108,7 +110,7 @@ static inline int apk_digest_ctx_final(struct apk_digest_ctx *dctx, struct apk_d return -APKE_CRYPTO_ERROR; } d->alg = dctx->alg; - d->len = mdlen; + d->len = apk_digest_alg_len(d->alg); return 0; } diff --git a/src/apk_database.h b/src/apk_database.h index e65a1de..587aefb 100644 --- a/src/apk_database.h +++ b/src/apk_database.h @@ -237,4 +237,12 @@ void apk_name_foreach_matching(struct apk_database *db, struct apk_string_array void (*cb)(struct apk_database *db, const char *match, struct apk_name *name, void *ctx), void *ctx); +static inline uint8_t apk_dbf_digest(struct apk_db_file *dbf) +{ + uint8_t alg = apk_digest_alg_by_len(dbf->csum.type); + if (alg == APK_DIGEST_SHA1 && dbf->diri->pkg->ipkg->sha256_160) + alg = APK_DIGEST_SHA256_160; + return alg; +} + #endif diff --git a/src/apk_package.h b/src/apk_package.h index 246b2ae..d94d73a 100644 --- a/src/apk_package.h +++ b/src/apk_package.h @@ -67,6 +67,7 @@ struct apk_installed_package { unsigned broken_files : 1; unsigned broken_script : 1; unsigned broken_xattr : 1; + unsigned sha256_160 : 1; }; struct apk_package { diff --git a/src/app_audit.c b/src/app_audit.c index 09d67e0..0557a0f 100644 --- a/src/app_audit.c +++ b/src/app_audit.c @@ -100,7 +100,7 @@ static int audit_file(struct audit_ctx *actx, if (apk_fileinfo_get(dirfd, name, APK_FI_NOFOLLOW | APK_FI_XATTR_CSUM(dbf->acl->xattr_csum.type ?: APK_CHECKSUM_DEFAULT) | - APK_FI_CSUM(dbf->csum.type), + APK_FI_DIGEST(apk_dbf_digest(dbf)), &fi, &db->atoms) != 0) return -EPERM; diff --git a/src/crypto_openssl.c b/src/crypto_openssl.c index 73f1879..a9eda6f 100644 --- a/src/crypto_openssl.c +++ b/src/crypto_openssl.c @@ -11,6 +11,7 @@ static const char *apk_digest_str[] = { [APK_DIGEST_NONE] = "none", [APK_DIGEST_MD5] = "md5", [APK_DIGEST_SHA1] = "sha1", + [APK_DIGEST_SHA256_160] = "sha256-160", [APK_DIGEST_SHA256] = "sha256", [APK_DIGEST_SHA512] = "sha512", }; @@ -26,11 +27,12 @@ const char *apk_digest_alg_str(uint8_t alg) int apk_digest_alg_len(uint8_t alg) { switch (alg) { - case APK_DIGEST_MD5: return 16; - case APK_DIGEST_SHA1: return 20; - case APK_DIGEST_SHA256: return 32; - case APK_DIGEST_SHA512: return 64; - default: return 0; + case APK_DIGEST_MD5: return 16; + case APK_DIGEST_SHA1: return 20; + case APK_DIGEST_SHA256_160: return 20; + case APK_DIGEST_SHA256: return 32; + case APK_DIGEST_SHA512: return 64; + default: return 0; } } diff --git a/src/database.c b/src/database.c index 144dd34..f8dd440 100644 --- a/src/database.c +++ b/src/database.c @@ -866,6 +866,7 @@ int apk_db_index_read(struct apk_database *db, struct apk_istream *is, int repo) case 'f': ipkg->broken_files = 1; break; case 's': ipkg->broken_script = 1; break; case 'x': ipkg->broken_xattr = 1; break; + case 'S': ipkg->sha256_160 = 1; break; default: if (!(db->ctx->force & APK_FORCE_OLD_APK)) goto old_apk_tools; @@ -943,7 +944,7 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os) apk_blob_push_blob(&bbuf, db->repo_tags[ipkg->repository_tag].plain_name); apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n")); } - if (ipkg->broken_files || ipkg->broken_script || ipkg->broken_xattr) { + if (ipkg->broken_files || ipkg->broken_script || ipkg->broken_xattr || ipkg->sha256_160) { apk_blob_push_blob(&bbuf, APK_BLOB_STR("f:")); if (ipkg->broken_files) apk_blob_push_blob(&bbuf, APK_BLOB_STR("f")); @@ -951,6 +952,8 @@ static int apk_db_write_fdb(struct apk_database *db, struct apk_ostream *os) apk_blob_push_blob(&bbuf, APK_BLOB_STR("s")); if (ipkg->broken_xattr) apk_blob_push_blob(&bbuf, APK_BLOB_STR("x")); + if (ipkg->sha256_160) + apk_blob_push_blob(&bbuf, APK_BLOB_STR("S")); apk_blob_push_blob(&bbuf, APK_BLOB_STR("\n")); } hlist_for_each_entry(diri, c1, &ipkg->owned_dirs, pkg_dirs_list) { @@ -2580,9 +2583,13 @@ static int apk_db_install_file(struct apk_extract_ctx *ectx, const struct apk_fi PKG_VER_PRINTF(pkg)); ipkg->broken_files = 1; ctx->missing_checksum = 1; + } else if (file->csum.type == APK_CHECKSUM_NONE && ae->digest.alg == APK_DIGEST_SHA256) { + ipkg->sha256_160 = 1; + file->csum.type = APK_CHECKSUM_SHA1; + memcpy(file->csum.data, ae->digest.data, file->csum.type); } else if (file->csum.type == APK_CHECKSUM_NONE && !ctx->missing_checksum) { apk_warn(out, - PKG_VER_FMT": v3 checksums ignored", + PKG_VER_FMT": unknown v3 checksum", PKG_VER_PRINTF(pkg)); ipkg->broken_files = 1; ctx->missing_checksum = 1; @@ -2652,7 +2659,7 @@ static void apk_db_purge_pkg(struct apk_database *db, if ((diri->dir->protect_mode == APK_PROTECT_NONE) || (db->ctx->flags & APK_PURGE) || (file->csum.type != APK_CHECKSUM_NONE && - apk_fileinfo_get(db->root_fd, name, APK_FI_NOFOLLOW | APK_FI_CSUM(file->csum.type), &fi, &db->atoms) == 0 && + apk_fileinfo_get(db->root_fd, name, APK_FI_NOFOLLOW | APK_FI_DIGEST(apk_dbf_digest(file)), &fi, &db->atoms) == 0 && apk_digest_cmp_csum(&fi.digest, &file->csum) == 0)) unlinkat(db->root_fd, name, 0); apk_dbg2(out, "%s", name); @@ -2705,7 +2712,7 @@ static void apk_db_migrate_files(struct apk_database *db, * in db, and the file is in a protected path */ cstype = APK_CHECKSUM_NONE; if (ofile != NULL && diri->dir->protect_mode != APK_PROTECT_NONE) - cstype = APK_FI_CSUM(ofile->csum.type); + cstype = APK_FI_DIGEST(apk_dbf_digest(ofile)); cstype |= APK_FI_NOFOLLOW; r = apk_fileinfo_get(db->root_fd, name, cstype, &fi, &db->atoms); @@ -2726,7 +2733,7 @@ static void apk_db_migrate_files(struct apk_database *db, if (ofile == NULL || ofile->csum.type != file->csum.type) apk_fileinfo_get(db->root_fd, name, - APK_FI_NOFOLLOW |APK_FI_CSUM(file->csum.type), + APK_FI_NOFOLLOW |APK_FI_DIGEST(apk_dbf_digest(file)), &fi, &db->atoms); if ((db->ctx->flags & APK_CLEAN_PROTECTED) || (file->csum.type != APK_CHECKSUM_NONE &&