Commit 84e3786e authored by Timo Teräs's avatar Timo Teräs

db: fixes to package checksumming while installing it

parent be8b59db
......@@ -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,
......
......@@ -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;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment