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) {
|
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,
|
||||||
}
|
}
|
||||||
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 {
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
.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,
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
|
|
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;
|
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,
|
||||||
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)
|
||||||
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)
|
||||||
|
|
||||||
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)
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue