summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/archive.c19
-rw-r--r--src/database.c32
-rw-r--r--src/gunzip.c13
-rw-r--r--src/package.c37
4 files changed, 61 insertions, 40 deletions
diff --git a/src/archive.c b/src/archive.c
index b069f2d..7c26502 100644
--- a/src/archive.c
+++ b/src/archive.c
@@ -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:
diff --git a/src/database.c b/src/database.c
index 40c6bf3..65f8633 100644
--- a/src/database.c
+++ b/src/database.c
@@ -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,
diff --git a/src/gunzip.c b/src/gunzip.c
index 2b30d46..3f9a253 100644
--- a/src/gunzip.c
+++ b/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;
}
diff --git a/src/package.c b/src/package.c
index 28f7f6e..78f7cb6 100644
--- a/src/package.c
+++ b/src/package.c
@@ -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;
}