db: fixes to package checksumming while installing it
parent
be8b59dbe1
commit
84e3786e05
|
@ -129,10 +129,8 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
|
|||
while ((r = is->read(is, &buf, 512)) == 512) {
|
||||
offset += 512;
|
||||
if (buf.name[0] == '\0') {
|
||||
if (end) {
|
||||
r = 0;
|
||||
//break;
|
||||
}
|
||||
if (end)
|
||||
break;
|
||||
end++;
|
||||
continue;
|
||||
}
|
||||
|
@ -218,11 +216,18 @@ int apk_tar_parse(struct apk_istream *is, apk_archive_entry_parser parser,
|
|||
}
|
||||
EVP_MD_CTX_cleanup(&teis.mdctx);
|
||||
|
||||
if (r != 0) {
|
||||
apk_error("Bad TAR header (r=%d)", r);
|
||||
return -1;
|
||||
/* Read remaining end-of-archive records, to ensure we read all of
|
||||
* the file. The underlying istream is likely doing checksumming. */
|
||||
if (r == 512) {
|
||||
while ((r = is->read(is, &buf, 512)) == 512)
|
||||
if (buf.name[0] != 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check that there was no partial record */
|
||||
if (r != 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
|
|
@ -39,6 +39,7 @@ struct install_ctx {
|
|||
int script;
|
||||
struct apk_db_dir_instance *diri;
|
||||
struct apk_checksum data_csum;
|
||||
struct apk_sign_ctx sctx;
|
||||
|
||||
apk_progress_cb cb;
|
||||
void *cb_ctx;
|
||||
|
@ -1247,6 +1248,9 @@ static int apk_db_install_archive_entry(void *_ctx,
|
|||
const char *p;
|
||||
int r = 0, type = APK_SCRIPT_INVALID;
|
||||
|
||||
if (apk_sign_ctx_process_file(&ctx->sctx, ae, is) == 0)
|
||||
return 0;
|
||||
|
||||
/* Package metainfo and script processing */
|
||||
if (ae->name[0] == '.') {
|
||||
/* APK 2.0 format */
|
||||
|
@ -1329,12 +1333,12 @@ static int apk_db_install_archive_entry(void *_ctx,
|
|||
if (opkg->name != pkg->name) {
|
||||
if (!(apk_flags & APK_FORCE)) {
|
||||
apk_error("%s: Trying to overwrite %s "
|
||||
"owned by %s.\n",
|
||||
"owned by %s.",
|
||||
pkg->name->name, ae->name,
|
||||
opkg->name->name);
|
||||
return -1;
|
||||
}
|
||||
apk_warning("%s: Overwriting %s owned by %s.\n",
|
||||
apk_warning("%s: Overwriting %s owned by %s.",
|
||||
pkg->name->name, ae->name,
|
||||
opkg->name->name);
|
||||
}
|
||||
|
@ -1430,9 +1434,8 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
|||
struct install_ctx ctx;
|
||||
struct apk_bstream *bs = NULL;
|
||||
struct apk_istream *tar;
|
||||
struct apk_sign_ctx sctx;
|
||||
char pkgname[256], file[256];
|
||||
int i, need_copy = FALSE;
|
||||
int r, i, need_copy = FALSE;
|
||||
|
||||
snprintf(pkgname, sizeof(pkgname), "%s-%s.apk",
|
||||
newpkg->name->name, newpkg->version);
|
||||
|
@ -1487,17 +1490,17 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
|||
.cb = cb,
|
||||
.cb_ctx = cb_ctx,
|
||||
};
|
||||
apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY_IDENTITY, &newpkg->csum);
|
||||
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &sctx);
|
||||
apk_sign_ctx_free(&sctx);
|
||||
if (apk_tar_parse(tar, apk_db_install_archive_entry, &ctx) != 0)
|
||||
goto err_close;
|
||||
apk_sign_ctx_init(&ctx.sctx, APK_SIGN_VERIFY_IDENTITY, &newpkg->csum);
|
||||
tar = apk_bstream_gunzip_mpart(bs, apk_sign_ctx_mpart_cb, &ctx.sctx);
|
||||
r = apk_tar_parse(tar, apk_db_install_archive_entry, &ctx);
|
||||
apk_sign_ctx_free(&ctx.sctx);
|
||||
tar->close(tar);
|
||||
|
||||
/* Check the package checksum */
|
||||
if (apk_checksum_compare(&ctx.data_csum, &newpkg->csum) != 0)
|
||||
apk_warning("%s-%s: checksum does not match",
|
||||
newpkg->name->name, newpkg->version);
|
||||
if (r != 0) {
|
||||
apk_error("%s-%s: package integrity check failed",
|
||||
newpkg->name->name, newpkg->version);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (need_copy) {
|
||||
char file2[256];
|
||||
|
@ -1507,9 +1510,6 @@ static int apk_db_unpack_pkg(struct apk_database *db,
|
|||
}
|
||||
|
||||
return 0;
|
||||
err_close:
|
||||
bs->close(bs, NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int apk_db_install_pkg(struct apk_database *db,
|
||||
|
|
13
src/gunzip.c
13
src/gunzip.c
|
@ -62,9 +62,16 @@ static size_t gzi_read(void *stream, void *ptr, size_t size)
|
|||
gis->z_err = Z_DATA_ERROR;
|
||||
return size - gis->zs.avail_out;
|
||||
} else if (gis->zs.avail_in == 0) {
|
||||
if (gis->cb != NULL)
|
||||
gis->cb(gis->cbctx, APK_MPART_END,
|
||||
APK_BLOB_NULL);
|
||||
if (gis->cb != NULL) {
|
||||
r = gis->cb(gis->cbctx, APK_MPART_END,
|
||||
APK_BLOB_NULL);
|
||||
if (r != 0) {
|
||||
gis->z_err = Z_STREAM_END;
|
||||
if (r > 0)
|
||||
r = -1;
|
||||
return r;
|
||||
}
|
||||
}
|
||||
gis->z_err = Z_STREAM_END;
|
||||
return size - gis->zs.avail_out;
|
||||
}
|
||||
|
|
|
@ -275,7 +275,6 @@ void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action,
|
|||
ctx->md = EVP_md5();
|
||||
ctx->control_started = 1;
|
||||
ctx->data_started = 1;
|
||||
ctx->has_data_checksum = 1;
|
||||
} else {
|
||||
ctx->md = EVP_sha1();
|
||||
}
|
||||
|
@ -438,7 +437,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data)
|
|||
sctx->signature.data.len,
|
||||
sctx->signature.pkey);
|
||||
if (r != 1)
|
||||
return 1;
|
||||
return -1;
|
||||
|
||||
sctx->control_verified = 1;
|
||||
EVP_DigestInit_ex(&sctx->mdctx, sctx->md, NULL);
|
||||
|
@ -457,9 +456,9 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data)
|
|||
|
||||
if (sctx->action == APK_SIGN_VERIFY_IDENTITY) {
|
||||
if (memcmp(calculated, sctx->identity.data,
|
||||
sctx->identity.type) == 0)
|
||||
sctx->control_verified = 1;
|
||||
return 1;
|
||||
sctx->identity.type) != 0)
|
||||
return -1;
|
||||
sctx->control_verified = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -467,29 +466,39 @@ int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data)
|
|||
if (sctx->has_data_checksum) {
|
||||
/* Check that data checksum matches */
|
||||
EVP_DigestFinal_ex(&sctx->mdctx, calculated, NULL);
|
||||
if (EVP_MD_CTX_size(&sctx->mdctx) != 0 &&
|
||||
if (EVP_MD_CTX_size(&sctx->mdctx) == 0 ||
|
||||
memcmp(calculated, sctx->data_checksum,
|
||||
EVP_MD_CTX_size(&sctx->mdctx)) == 0)
|
||||
sctx->data_verified = 1;
|
||||
EVP_MD_CTX_size(&sctx->mdctx)) != 0)
|
||||
return -1;
|
||||
sctx->data_verified = 1;
|
||||
} else if (sctx->action == APK_SIGN_VERIFY) {
|
||||
if (sctx->signature.pkey == NULL)
|
||||
return 1;
|
||||
return -1;
|
||||
|
||||
/* Assume that the data is fully signed */
|
||||
r = EVP_VerifyFinal(&sctx->mdctx,
|
||||
(unsigned char *) sctx->signature.data.ptr,
|
||||
sctx->signature.data.len,
|
||||
sctx->signature.pkey);
|
||||
if (r == 1) {
|
||||
sctx->control_verified = 1;
|
||||
sctx->data_verified = 1;
|
||||
}
|
||||
if (r != 1)
|
||||
return -1;
|
||||
|
||||
sctx->control_verified = 1;
|
||||
sctx->data_verified = 1;
|
||||
} else if (sctx->action == APK_SIGN_VERIFY_IDENTITY) {
|
||||
EVP_DigestFinal_ex(&sctx->mdctx, calculated, NULL);
|
||||
if (EVP_MD_CTX_size(&sctx->mdctx) == 0 ||
|
||||
memcmp(calculated, sctx->identity.data,
|
||||
EVP_MD_CTX_size(&sctx->mdctx)) != 0)
|
||||
return -1;
|
||||
sctx->control_verified = 1;
|
||||
sctx->data_verified = 1;
|
||||
} else {
|
||||
/* Package identity is checksum of all data */
|
||||
sctx->identity.type = EVP_MD_CTX_size(&sctx->mdctx);
|
||||
EVP_DigestFinal_ex(&sctx->mdctx, sctx->identity.data, NULL);
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue