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

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