summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/apk_io.h11
-rw-r--r--src/apk_package.h3
-rw-r--r--src/database.c22
-rw-r--r--src/gunzip.c44
-rw-r--r--src/io.c3
-rw-r--r--src/package.c43
6 files changed, 61 insertions, 65 deletions
diff --git a/src/apk_io.h b/src/apk_io.h
index e547668..fe6baac 100644
--- a/src/apk_io.h
+++ b/src/apk_io.h
@@ -35,7 +35,10 @@ struct apk_istream {
void (*close)(void *stream);
};
+#define APK_BSTREAM_SINGLE_READ 0x0001
+
struct apk_bstream {
+ unsigned int flags;
apk_blob_t (*read)(void *stream, apk_blob_t token);
void (*close)(void *stream, size_t *size);
};
@@ -45,11 +48,11 @@ struct apk_ostream {
void (*close)(void *stream);
};
-#define APK_MPART_BEGIN 0
-#define APK_MPART_BOUNDARY 1
-#define APK_MPART_END 2
+#define APK_MPART_DATA 1 /* data processed so far */
+#define APK_MPART_BOUNDARY 2 /* final part of data, before boundary */
+#define APK_MPART_END 3 /* signals end of stream */
-typedef int (*apk_multipart_cb)(void *ctx, EVP_MD_CTX *mdctx, int part);
+typedef int (*apk_multipart_cb)(void *ctx, int part, apk_blob_t data);
struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *,
apk_multipart_cb cb, void *ctx);
diff --git a/src/apk_package.h b/src/apk_package.h
index 6b7e959..f77637a 100644
--- a/src/apk_package.h
+++ b/src/apk_package.h
@@ -45,6 +45,7 @@ struct apk_sign_ctx {
int data_verified : 1;
char data_checksum[EVP_MAX_MD_SIZE];
struct apk_checksum identity;
+ EVP_MD_CTX mdctx;
struct {
apk_blob_t data;
@@ -97,7 +98,7 @@ void apk_sign_ctx_free(struct apk_sign_ctx *ctx);
int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
const struct apk_file_info *fi,
struct apk_istream *is);
-int apk_sign_ctx_mpart_cb(void *ctx, EVP_MD_CTX *mdctx, int part);
+int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t blob);
int apk_deps_add(struct apk_dependency_array **depends,
struct apk_dependency *dep);
diff --git a/src/database.c b/src/database.c
index 5a1348e..db8f521 100644
--- a/src/database.c
+++ b/src/database.c
@@ -1332,22 +1332,6 @@ static void apk_db_purge_pkg(struct apk_database *db,
apk_pkg_set_state(db, pkg, APK_PKG_NOT_INSTALLED);
}
-static int apk_db_gzip_part(void *pctx, EVP_MD_CTX *mdctx, int part)
-{
- struct install_ctx *ctx = (struct install_ctx *) pctx;
-
- switch (part) {
- case APK_MPART_BEGIN:
- EVP_DigestInit_ex(mdctx, EVP_md5(), NULL);
- break;
- case APK_MPART_END:
- ctx->data_csum.type = EVP_MD_CTX_size(mdctx);
- EVP_DigestFinal_ex(mdctx, ctx->data_csum.data, NULL);
- break;
- }
- return 0;
-}
-
static int apk_db_unpack_pkg(struct apk_database *db,
struct apk_package *newpkg,
int upgrade, apk_progress_cb cb, void *cb_ctx)
@@ -1355,6 +1339,7 @@ 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;
@@ -1411,8 +1396,9 @@ static int apk_db_unpack_pkg(struct apk_database *db,
.cb = cb,
.cb_ctx = cb_ctx,
};
-
- tar = apk_bstream_gunzip_mpart(bs, apk_db_gzip_part, &ctx);
+ apk_sign_ctx_init(&sctx, APK_SIGN_VERIFY);
+ 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;
tar->close(tar);
diff --git a/src/gunzip.c b/src/gunzip.c
index 9c9ea69..fb0da05 100644
--- a/src/gunzip.c
+++ b/src/gunzip.c
@@ -23,17 +23,16 @@ struct apk_gzip_istream {
z_stream zs;
int z_err;
- EVP_MD_CTX mdctx;
- void *mdblock;
-
apk_multipart_cb cb;
void *cbctx;
+ void *cbprev;
};
static size_t gzi_read(void *stream, void *ptr, size_t size)
{
struct apk_gzip_istream *gis =
container_of(stream, struct apk_gzip_istream, is);
+ int r;
if (gis->z_err == Z_DATA_ERROR || gis->z_err == Z_ERRNO)
return -1;
@@ -50,22 +49,22 @@ static size_t gzi_read(void *stream, void *ptr, size_t size)
if (gis->zs.avail_in == 0) {
apk_blob_t blob;
- if (gis->cb != NULL && gis->mdblock != NULL) {
- /* Digest the inflated bytes */
- EVP_DigestUpdate(&gis->mdctx, gis->mdblock,
- (void *)gis->zs.next_in - gis->mdblock);
+ if (gis->cb != NULL && gis->cbprev != NULL) {
+ gis->cb(gis->cbctx, APK_MPART_DATA,
+ APK_BLOB_PTR_LEN(gis->cbprev,
+ (void *)gis->zs.next_in - gis->cbprev));
}
blob = gis->bs->read(gis->bs, APK_BLOB_NULL);
- gis->mdblock = blob.ptr;
+ gis->cbprev = blob.ptr;
gis->zs.avail_in = blob.len;
- gis->zs.next_in = (void *) gis->mdblock;
+ gis->zs.next_in = (void *) gis->cbprev;
if (gis->zs.avail_in < 0) {
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, &gis->mdctx,
- APK_MPART_END);
+ gis->cb(gis->cbctx, APK_MPART_END,
+ APK_BLOB_NULL);
gis->z_err = Z_STREAM_END;
return size - gis->zs.avail_out;
}
@@ -75,14 +74,16 @@ static size_t gzi_read(void *stream, void *ptr, size_t size)
if (gis->z_err == Z_STREAM_END) {
/* Digest the inflated bytes */
if (gis->cb != NULL) {
- EVP_DigestUpdate(&gis->mdctx, gis->mdblock,
- (void *)gis->zs.next_in - gis->mdblock);
- gis->mdblock = gis->zs.next_in;
- if (gis->cb(gis->cbctx, &gis->mdctx,
- APK_MPART_BOUNDARY)) {
- gis->z_err = Z_STREAM_END;
- break;
+ r = gis->cb(gis->cbctx, APK_MPART_BOUNDARY,
+ APK_BLOB_PTR_LEN(gis->cbprev,
+ (void *)gis->zs.next_in - gis->cbprev));
+ if (r != 0) {
+ gis->z_err = Z_DATA_ERROR;
+ if (r > 0)
+ r = -1;
+ return r;
}
+ gis->cbprev = gis->zs.next_in;
}
inflateEnd(&gis->zs);
if (inflateInit2(&gis->zs, 15+32) != Z_OK)
@@ -102,8 +103,6 @@ static void gzi_close(void *stream)
struct apk_gzip_istream *gis =
container_of(stream, struct apk_gzip_istream, is);
- if (gis->cb != NULL)
- EVP_MD_CTX_cleanup(&gis->mdctx);
inflateEnd(&gis->zs);
gis->bs->close(gis->bs, NULL);
free(gis);
@@ -135,11 +134,6 @@ struct apk_istream *apk_bstream_gunzip_mpart(struct apk_bstream *bs,
goto err;
}
- if (gis->cb != NULL) {
- EVP_MD_CTX_init(&gis->mdctx);
- cb(ctx, &gis->mdctx, APK_MPART_BEGIN);
- }
-
return &gis->is;
err:
bs->close(bs, NULL);
diff --git a/src/io.c b/src/io.c
index c7846c9..e7ed16e 100644
--- a/src/io.c
+++ b/src/io.c
@@ -295,6 +295,7 @@ static struct apk_bstream *apk_mmap_bstream_from_fd(int fd)
}
mbs->bs = (struct apk_bstream) {
+ .flags = APK_BSTREAM_SINGLE_READ,
.read = mmap_read,
.close = mmap_close,
};
@@ -466,6 +467,8 @@ int apk_file_get_info(const char *filename, int checksum, struct apk_file_info *
apk_blob_t blob;
EVP_DigestInit(&mdctx, apk_get_digest(checksum));
+ if (bs->flags & APK_BSTREAM_SINGLE_READ)
+ EVP_MD_CTX_set_flags(&mdctx, EVP_MD_CTX_FLAG_ONESHOT);
while (!APK_BLOB_IS_NULL(blob = bs->read(bs, APK_BLOB_NULL)))
EVP_DigestUpdate(&mdctx, (void*) blob.ptr, blob.len);
fi->csum.type = EVP_MD_CTX_size(&mdctx);
diff --git a/src/package.c b/src/package.c
index 632e93e..4a90993 100644
--- a/src/package.c
+++ b/src/package.c
@@ -275,6 +275,9 @@ void apk_sign_ctx_init(struct apk_sign_ctx *ctx, int action)
ctx->md = EVP_sha1();
break;
}
+ EVP_MD_CTX_init(&ctx->mdctx);
+ EVP_DigestInit_ex(&ctx->mdctx, ctx->md, NULL);
+ EVP_MD_CTX_set_flags(&ctx->mdctx, EVP_MD_CTX_FLAG_ONESHOT);
}
@@ -338,22 +341,26 @@ int apk_sign_ctx_process_file(struct apk_sign_ctx *ctx,
return 0;
}
-int apk_sign_ctx_mpart_cb(void *ctx, EVP_MD_CTX *mdctx, int part)
+int apk_sign_ctx_mpart_cb(void *ctx, int part, apk_blob_t data)
{
struct apk_sign_ctx *sctx = (struct apk_sign_ctx *) ctx;
unsigned char calculated[EVP_MAX_MD_SIZE];
int r;
switch (part) {
- case APK_MPART_BEGIN:
- EVP_DigestInit_ex(mdctx, sctx->md, NULL);
+ case APK_MPART_DATA:
+ EVP_MD_CTX_clear_flags(&sctx->mdctx, EVP_MD_CTX_FLAG_ONESHOT);
+ EVP_DigestUpdate(&sctx->mdctx, data.ptr, data.len);
break;
case APK_MPART_BOUNDARY:
+ EVP_DigestUpdate(&sctx->mdctx, data.ptr, data.len);
+
/* We are not interested about checksums of signature,
* reset checksum if we are still in signatures */
if (!sctx->control_started) {
- EVP_DigestFinal_ex(mdctx, calculated, NULL);
- EVP_DigestInit_ex(mdctx, sctx->md, NULL);
+ EVP_DigestFinal_ex(&sctx->mdctx, calculated, NULL);
+ EVP_DigestInit_ex(&sctx->mdctx, sctx->md, NULL);
+ EVP_MD_CTX_set_flags(&sctx->mdctx, EVP_MD_CTX_FLAG_ONESHOT);
return 0;
}
@@ -367,7 +374,7 @@ int apk_sign_ctx_mpart_cb(void *ctx, EVP_MD_CTX *mdctx, int part)
/* Verify the signature if we have public key */
if (sctx->action == APK_SIGN_VERIFY &&
sctx->signature.pkey != NULL) {
- r = EVP_VerifyFinal(mdctx,
+ r = EVP_VerifyFinal(&sctx->mdctx,
(unsigned char *) sctx->signature.data.ptr,
sctx->signature.data.len,
sctx->signature.pkey);
@@ -375,32 +382,34 @@ int apk_sign_ctx_mpart_cb(void *ctx, EVP_MD_CTX *mdctx, int part)
return 1;
sctx->control_verified = 1;
- EVP_DigestInit_ex(mdctx, sctx->md, NULL);
+ EVP_DigestInit_ex(&sctx->mdctx, sctx->md, NULL);
+ EVP_MD_CTX_set_flags(&sctx->mdctx, EVP_MD_CTX_FLAG_ONESHOT);
return 0;
} else if (sctx->action == APK_SIGN_GENERATE &&
sctx->has_data_checksum) {
/* Package identity is checksum of control block */
- sctx->identity.type = EVP_MD_CTX_size(mdctx);
- EVP_DigestFinal_ex(mdctx, sctx->identity.data, NULL);
+ sctx->identity.type = EVP_MD_CTX_size(&sctx->mdctx);
+ EVP_DigestFinal_ex(&sctx->mdctx, sctx->identity.data, NULL);
return 1;
} else {
/* Reset digest for hashing data */
- EVP_DigestFinal_ex(mdctx, calculated, NULL);
- EVP_DigestInit_ex(mdctx, sctx->md, NULL);
+ EVP_DigestFinal_ex(&sctx->mdctx, calculated, NULL);
+ EVP_DigestInit_ex(&sctx->mdctx, sctx->md, NULL);
+ EVP_MD_CTX_set_flags(&sctx->mdctx, EVP_MD_CTX_FLAG_ONESHOT);
}
break;
case APK_MPART_END:
if (sctx->action == APK_SIGN_VERIFY) {
if (sctx->has_data_checksum) {
/* Check that data checksum matches */
- EVP_DigestFinal_ex(mdctx, calculated, NULL);
- if (EVP_MD_CTX_size(mdctx) != 0 &&
+ EVP_DigestFinal_ex(&sctx->mdctx, calculated, NULL);
+ if (EVP_MD_CTX_size(&sctx->mdctx) != 0 &&
memcmp(calculated, sctx->data_checksum,
- EVP_MD_CTX_size(mdctx)) == 0)
+ EVP_MD_CTX_size(&sctx->mdctx)) == 0)
sctx->data_verified = 1;
} else if (sctx->signature.pkey != NULL) {
/* Assume that the data is fully signed */
- r = EVP_VerifyFinal(mdctx,
+ r = EVP_VerifyFinal(&sctx->mdctx,
(unsigned char *) sctx->signature.data.ptr,
sctx->signature.data.len,
sctx->signature.pkey);
@@ -411,8 +420,8 @@ int apk_sign_ctx_mpart_cb(void *ctx, EVP_MD_CTX *mdctx, int part)
}
} else if (!sctx->has_data_checksum) {
/* Package identity is checksum of all data */
- sctx->identity.type = EVP_MD_CTX_size(mdctx);
- EVP_DigestFinal_ex(mdctx, sctx->identity.data, NULL);
+ sctx->identity.type = EVP_MD_CTX_size(&sctx->mdctx);
+ EVP_DigestFinal_ex(&sctx->mdctx, sctx->identity.data, NULL);
}
return 1;
}