db, audit: support sha256-160 hashes for v3 pkg compat

cute-signatures
Timo Teräs 2021-10-25 17:14:00 +03:00
parent 40f0866367
commit 6941aac4c6
6 changed files with 33 additions and 13 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -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 {

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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 &&