From 0c12ac1473e36a983d168b050c0850be4f01f259 Mon Sep 17 00:00:00 2001 From: Lars Erik Wik Date: Thu, 3 Oct 2024 14:13:08 +0200 Subject: [PATCH] feat: added integrity checks for artifact data files The client now performs integrity checks on the data files in the artifact by comparing its computed checksum to the one in the artifact manifest. Ticket: MEN-7483 Changelog: Commit Signed-off-by: Lars Erik Wik --- core/src/mender-artifact.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/core/src/mender-artifact.c b/core/src/mender-artifact.c index 9dd4c3a..d43bc89 100644 --- a/core/src/mender-artifact.c +++ b/core/src/mender-artifact.c @@ -211,7 +211,8 @@ mender_artifact_check_integrity(mender_artifact_ctx_t *ctx) { for (mender_artifact_checksum_t *checksum = ctx->artifact_info.checksums; NULL != checksum; checksum = checksum->next) { unsigned char computed[MENDER_DIGEST_BUFFER_SIZE]; - if (!StringEqual(checksum->filename, "version") && !StringEqual(checksum->filename, "header.tar")) { + if (!StringEqual(checksum->filename, "version") && !StringEqual(checksum->filename, "header.tar") + && !mender_utils_strbeginwith(checksum->filename, "data/")) { /* Whenever we introduce a new file to the artifact manifest, we * need to skip integrity checks for that file until it's * implemented. Otherwise, the client will get stuck trying to @@ -1072,6 +1073,37 @@ mender_artifact_read_data(mender_artifact_ctx_t *ctx, mender_err_t (*callback)(c size_t length = ((ctx->file.size - ctx->file.index) > MENDER_ARTIFACT_STREAM_BLOCK_SIZE) ? MENDER_ARTIFACT_STREAM_BLOCK_SIZE : (ctx->file.size - ctx->file.index); +#ifdef CONFIG_MENDER_FULL_PARSE_ARTIFACT + mender_artifact_checksum_t *checksum; + { + /* The filename will be something like + * 'data/0000.tar/zephyr.signed.bin'. But the manifest will hold + * 'data/0000/zephyr.signed.bin'. Hence, we need to remove the + * '.tar' extension from the string. + */ + char filename[strlen(ctx->file.name) + 1]; + strcpy(filename, ctx->file.name); + + for (char *ch = strstr(filename, ".tar"); (NULL != ch) && (*ch != '\0'); ch++) { + /* Don't worry! The call to strlen() on a static string should + * be optimized out by the compiler */ + *ch = ch[strlen(".tar")]; + } + + /* Get checksum entry (create one if needed) */ + if (NULL == (checksum = mender_artifact_checksum_get_or_create(ctx, filename))) { + /* Error already logged */ + return MENDER_FAIL; + } + } + + /* Update SHA-256 checksum */ + if (MENDER_OK != mender_sha256_update(checksum->context, ctx->input.data, length)) { + mender_log_error("Failed to update update checksum"); + return MENDER_FAIL; + } +#endif /* CONFIG_MENDER_FULL_PARSE_ARTIFACT */ + /* Invoke callback */ if (MENDER_OK != (ret = callback(ctx->payloads.values[index].type,