diff --git a/src/libostree/ostree-core-private.h b/src/libostree/ostree-core-private.h index 0658a0cbbd..70b12b68c7 100644 --- a/src/libostree/ostree-core-private.h +++ b/src/libostree/ostree-core-private.h @@ -20,6 +20,7 @@ #pragma once #include "ostree-core.h" +#include "otutil.h" #include G_BEGIN_DECLS @@ -77,7 +78,7 @@ gboolean _ostree_write_variant_with_size (GOutputStream *output, GVariant *variant, guint64 alignment_offset, gsize *out_bytes_written, - GChecksum *checksum, + OtChecksum *checksum, GCancellable *cancellable, GError **error); diff --git a/src/libostree/ostree-core.c b/src/libostree/ostree-core.c index 7fa051f2ff..2fafe99d70 100644 --- a/src/libostree/ostree-core.c +++ b/src/libostree/ostree-core.c @@ -358,7 +358,7 @@ write_padding (GOutputStream *output, guint alignment, gsize offset, gsize *out_bytes_written, - GChecksum *checksum, + OtChecksum *checksum, GCancellable *cancellable, GError **error) { @@ -403,7 +403,7 @@ _ostree_write_variant_with_size (GOutputStream *output, GVariant *variant, guint64 alignment_offset, gsize *out_bytes_written, - GChecksum *checksum, + OtChecksum *checksum, GCancellable *cancellable, GError **error) { @@ -458,7 +458,7 @@ _ostree_write_variant_with_size (GOutputStream *output, static gboolean write_file_header_update_checksum (GOutputStream *out, GVariant *header, - GChecksum *checksum, + OtChecksum *checksum, GCancellable *cancellable, GError **error) { @@ -859,18 +859,19 @@ ostree_checksum_file_from_input (GFileInfo *file_info, GError **error) { - g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256); + g_auto(OtChecksum) checksum = { 0, }; + ot_checksum_init (&checksum); if (OSTREE_OBJECT_TYPE_IS_META (objtype)) { - if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error)) + if (!ot_gio_splice_update_checksum (NULL, in, &checksum, cancellable, error)) return FALSE; } else if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) { g_autoptr(GVariant) dirmeta = ostree_create_directory_metadata (file_info, xattrs); - g_checksum_update (checksum, g_variant_get_data (dirmeta), - g_variant_get_size (dirmeta)); + ot_checksum_update (&checksum, g_variant_get_data (dirmeta), + g_variant_get_size (dirmeta)); } else { @@ -878,18 +879,19 @@ ostree_checksum_file_from_input (GFileInfo *file_info, file_header = _ostree_file_header_new (file_info, xattrs); - if (!write_file_header_update_checksum (NULL, file_header, checksum, + if (!write_file_header_update_checksum (NULL, file_header, &checksum, cancellable, error)) return FALSE; if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_REGULAR) { - if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error)) + if (!ot_gio_splice_update_checksum (NULL, in, &checksum, cancellable, error)) return FALSE; } } - *out_csum = ot_csum_from_gchecksum (checksum); + *out_csum = g_malloc (OSTREE_SHA256_DIGEST_LEN); + ot_checksum_get_digest (&checksum, *out_csum, OSTREE_SHA256_DIGEST_LEN); return TRUE; } diff --git a/src/libostree/ostree-repo-commit.c b/src/libostree/ostree-repo-commit.c index 2bffbae39d..377adc754d 100644 --- a/src/libostree/ostree-repo-commit.c +++ b/src/libostree/ostree-repo-commit.c @@ -811,14 +811,19 @@ write_metadata_object (OstreeRepo *self, * *original* sha256 to say what commit was being killed. */ const gboolean is_tombstone = (objtype == OSTREE_OBJECT_TYPE_TOMBSTONE_COMMIT); - g_autofree char *actual_checksum = NULL; + char actual_checksum[OSTREE_SHA256_STRING_LEN+1]; if (is_tombstone) { - actual_checksum = g_strdup (expected_checksum); + memcpy (actual_checksum, expected_checksum, sizeof (actual_checksum)); } else { - actual_checksum = g_compute_checksum_for_bytes (G_CHECKSUM_SHA256, buf); + OtChecksum checksum = { 0, }; + ot_checksum_init (&checksum); + gsize len; + const guint8*bufdata = g_bytes_get_data (buf, &len); + ot_checksum_update (&checksum, bufdata, len); + ot_checksum_get_hexdigest (&checksum, actual_checksum, sizeof (actual_checksum)); gboolean have_obj; if (!_ostree_repo_has_loose_object (self, actual_checksum, objtype, &have_obj, cancellable, error)) diff --git a/src/libostree/ostree-repo-static-delta-processing.c b/src/libostree/ostree-repo-static-delta-processing.c index 844de2c653..fca0f21610 100644 --- a/src/libostree/ostree-repo-static-delta-processing.c +++ b/src/libostree/ostree-repo-static-delta-processing.c @@ -58,7 +58,7 @@ typedef struct { GLnxTmpfile tmpf; guint64 content_size; GOutputStream *content_out; - GChecksum *content_checksum; + OtChecksum content_checksum; char checksum[OSTREE_SHA256_STRING_LEN+1]; char *read_source_object; int read_source_fd; @@ -277,7 +277,7 @@ _ostree_static_delta_part_execute (OstreeRepo *repo, out: glnx_tmpfile_clear (&state->tmpf); g_clear_object (&state->content_out); - g_clear_pointer (&state->content_checksum, g_checksum_free); + ot_checksum_clear (&state->content_checksum); return ret; } @@ -385,8 +385,8 @@ content_out_write (OstreeRepo *repo, { gsize bytes_written; - if (state->content_checksum) - g_checksum_update (state->content_checksum, buf, len); + if (state->content_checksum.initialized) + ot_checksum_update (&state->content_checksum, buf, len); /* Ignore bytes_written since we discard partial content */ if (!g_output_stream_write_all (state->content_out, @@ -503,10 +503,10 @@ handle_untrusted_content_checksum (OstreeRepo *repo, g_autoptr(GFileInfo) finfo = _ostree_mode_uidgid_to_gfileinfo (state->mode, state->uid, state->gid); g_autoptr(GVariant) header = _ostree_file_header_new (finfo, state->xattrs); - state->content_checksum = g_checksum_new (G_CHECKSUM_SHA256); + ot_checksum_init (&state->content_checksum); gsize bytes_written; - if (!_ostree_write_variant_with_size (NULL, header, 0, &bytes_written, state->content_checksum, + if (!_ostree_write_variant_with_size (NULL, header, 0, &bytes_written, &state->content_checksum, cancellable, error)) return FALSE; @@ -827,9 +827,10 @@ dispatch_close (OstreeRepo *repo, if (!g_output_stream_flush (state->content_out, cancellable, error)) return FALSE; - if (state->content_checksum) + if (state->content_checksum.initialized) { - const char *actual_checksum = g_checksum_get_string (state->content_checksum); + char actual_checksum[OSTREE_SHA256_STRING_LEN+1]; + ot_checksum_get_hexdigest (&state->content_checksum, actual_checksum, sizeof (actual_checksum)); if (strcmp (actual_checksum, state->checksum) != 0) return glnx_throw (error, "Corrupted object %s (actual checksum is %s)", @@ -848,7 +849,7 @@ dispatch_close (OstreeRepo *repo, return FALSE; g_clear_pointer (&state->xattrs, g_variant_unref); - g_clear_pointer (&state->content_checksum, g_checksum_free); + ot_checksum_clear (&state->content_checksum); state->checksum_index++; state->output_target = NULL; diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 4f45303478..920c0eb47e 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -989,13 +989,14 @@ get_kernel_from_tree_usrlib_modules (int deployment_dfd, } /* We found a module directory, compute the checksum */ - g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256); + g_auto(OtChecksum) checksum = { 0, }; + ot_checksum_init (&checksum); glnx_fd_close int fd = -1; /* Checksum the kernel */ if (!glnx_openat_rdonly (ret_layout->boot_dfd, "vmlinuz", TRUE, &fd, error)) return FALSE; g_autoptr(GInputStream) in = g_unix_input_stream_new (fd, FALSE); - if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error)) + if (!ot_gio_splice_update_checksum (NULL, in, &checksum, cancellable, error)) return FALSE; g_clear_object (&in); (void) close (fd); fd = -1; @@ -1022,11 +1023,13 @@ get_kernel_from_tree_usrlib_modules (int deployment_dfd, ret_layout->initramfs_srcpath = g_strdup (initramfs_path); ret_layout->initramfs_namever = g_strdup_printf ("initramfs-%s.img", kver); in = g_unix_input_stream_new (fd, FALSE); - if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error)) + if (!ot_gio_splice_update_checksum (NULL, in, &checksum, cancellable, error)) return FALSE; } - ret_layout->bootcsum = g_strdup (g_checksum_get_string (checksum)); + char hexdigest[OSTREE_SHA256_STRING_LEN+1]; + ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest)); + ret_layout->bootcsum = g_strdup (hexdigest); *out_layout = g_steal_pointer (&ret_layout); return TRUE; diff --git a/src/libotutil/ot-checksum-instream.c b/src/libotutil/ot-checksum-instream.c index 368a337df5..342b14b4f7 100644 --- a/src/libotutil/ot-checksum-instream.c +++ b/src/libotutil/ot-checksum-instream.c @@ -22,25 +22,10 @@ #include "ot-checksum-instream.h" #include "ot-checksum-utils.h" -#if defined(HAVE_OPENSSL) -#include -#elif defined(HAVE_GNUTLS) -#include -#include -#endif - G_DEFINE_TYPE (OtChecksumInstream, ot_checksum_instream, G_TYPE_FILTER_INPUT_STREAM) struct _OtChecksumInstreamPrivate { -#if defined(HAVE_OPENSSL) - EVP_MD_CTX *checksum; -#elif defined(HAVE_GNUTLS) - gnutls_digest_algorithm_t checksum_type; - gnutls_hash_hd_t checksum; -#else - GChecksumType checksum_type; - GChecksum *checksum; -#endif + OtChecksum checksum; }; static gssize ot_checksum_instream_read (GInputStream *stream, @@ -54,13 +39,7 @@ ot_checksum_instream_finalize (GObject *object) { OtChecksumInstream *self = (OtChecksumInstream*)object; -#if defined(HAVE_OPENSSL) - EVP_MD_CTX_destroy (self->priv->checksum); -#elif defined(HAVE_GNUTLS) - gnutls_hash_deinit (self->priv->checksum, NULL); -#else - g_checksum_free (self->priv->checksum); -#endif + ot_checksum_clear (&self->priv->checksum); G_OBJECT_CLASS (ot_checksum_instream_parent_class)->finalize (object); } @@ -83,33 +62,6 @@ ot_checksum_instream_init (OtChecksumInstream *self) self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, OT_TYPE_CHECKSUM_INSTREAM, OtChecksumInstreamPrivate); } -#if defined(HAVE_OPENSSL) -static const EVP_MD * -gchecksum_type_to_openssl (GChecksumType checksum_type) -{ - switch (checksum_type) - { - case G_CHECKSUM_SHA256: - return EVP_sha256 (); - default: - /* If there's something else, fill in here */ - g_assert_not_reached (); - } -} -#elif defined(HAVE_GNUTLS) -static gnutls_digest_algorithm_t -gchecksum_type_to_gnutls (GChecksumType checksum_type) -{ - switch (checksum_type) - { - case G_CHECKSUM_SHA256: - return GNUTLS_DIG_SHA256; - default: - g_assert_not_reached (); - } -} -#endif - OtChecksumInstream * ot_checksum_instream_new (GInputStream *base, GChecksumType checksum_type) @@ -124,18 +76,7 @@ ot_checksum_instream_new (GInputStream *base, /* For now */ g_assert (checksum_type == G_CHECKSUM_SHA256); - -#if defined(HAVE_OPENSSL) - stream->priv->checksum = EVP_MD_CTX_create (); - g_assert (stream->priv->checksum); - g_assert (EVP_DigestInit_ex (stream->priv->checksum, gchecksum_type_to_openssl (checksum_type), NULL)); -#elif defined(HAVE_GNUTLS) - stream->priv->checksum_type = gchecksum_type_to_gnutls (checksum_type); - g_assert (!gnutls_hash_init (&stream->priv->checksum, stream->priv->checksum_type)); -#else - stream->priv->checksum = g_checksum_new (checksum_type); - stream->priv->checksum_type = checksum_type; -#endif + ot_checksum_init (&stream->priv->checksum); return (OtChecksumInstream*) (stream); } @@ -157,78 +98,15 @@ ot_checksum_instream_read (GInputStream *stream, cancellable, error); if (res > 0) - { -#if defined(HAVE_OPENSSL) - g_assert (EVP_DigestUpdate (self->priv->checksum, buffer, res)); -#elif defined(HAVE_GNUTLS) - g_assert (!gnutls_hash (self->priv->checksum, buffer, res)); -#else - g_checksum_update (self->priv->checksum, buffer, res); -#endif - } + ot_checksum_update (&self->priv->checksum, buffer, res); return res; } -void -ot_checksum_instream_get_digest (OtChecksumInstream *stream, - guint8 *buffer, - gsize *digest_len) -{ -#if defined(HAVE_OPENSSL) - unsigned len; - EVP_DigestFinal_ex (stream->priv->checksum, buffer, &len); - if (digest_len) - *digest_len = len; -#elif defined(HAVE_GNUTLS) - gnutls_hash_output (stream->priv->checksum, buffer); - if (digest_len) - *digest_len = gnutls_hash_get_len (stream->priv->checksum_type); -#else - g_checksum_get_digest (stream->priv->checksum, buffer, digest_len); -#endif -} - -guint8* -ot_checksum_instream_dup_digest (OtChecksumInstream *stream, - gsize *ret_len) -{ -#if defined(HAVE_OPENSSL) - guint len; - guchar *ret = g_malloc0 (EVP_MAX_MD_SIZE); - g_assert (EVP_DigestFinal_ex (stream->priv->checksum, ret, &len)); -#elif defined(HAVE_GNUTLS) - guint len = gnutls_hash_get_len (stream->priv->checksum_type); - guchar *ret = g_malloc0 (len); - gnutls_hash_output (stream->priv->checksum, ret); -#else - gsize len = g_checksum_type_get_length (stream->priv->checksum_type); - guchar *ret = g_malloc (len); - g_checksum_get_digest (stream->priv->checksum, ret, &len); -#endif - if (ret_len) - *ret_len = len; - return ret; -} - char * ot_checksum_instream_get_string (OtChecksumInstream *stream) { -#if defined(HAVE_OPENSSL) - unsigned len; - guint8 csum[EVP_MAX_MD_SIZE]; - g_assert (EVP_DigestFinal_ex (stream->priv->checksum, csum, &len)); - char *buf = g_malloc (len * 2 + 1); - ot_bin2hex (buf, (guint8*)csum, len); - return buf; -#elif defined(HAVE_GNUTLS) - gsize len; - guint8 *csum = ot_checksum_instream_dup_digest(stream, &len); - char *buf = g_malloc0 (len * 2 + 1); - ot_bin2hex (buf, csum, len); - g_free (csum); - return buf; -#else - return g_strdup (g_checksum_get_string (stream->priv->checksum)); -#endif + char buf[_OSTREE_SHA256_STRING_LEN+1]; + ot_checksum_get_hexdigest (&stream->priv->checksum, buf, sizeof(buf)); + return g_strndup (buf, sizeof(buf)); } diff --git a/src/libotutil/ot-checksum-instream.h b/src/libotutil/ot-checksum-instream.h index 6525aa91f5..410047a9e6 100644 --- a/src/libotutil/ot-checksum-instream.h +++ b/src/libotutil/ot-checksum-instream.h @@ -52,12 +52,6 @@ GType ot_checksum_instream_get_type (void) G_GNUC_CONST; OtChecksumInstream * ot_checksum_instream_new (GInputStream *stream, GChecksumType checksum); -void ot_checksum_instream_get_digest (OtChecksumInstream *stream, - guint8 *buffer, - gsize *digest_len); - -guint8* ot_checksum_instream_dup_digest (OtChecksumInstream *stream, - gsize *ret_len); char * ot_checksum_instream_get_string (OtChecksumInstream *stream); G_END_DECLS diff --git a/src/libotutil/ot-checksum-utils.c b/src/libotutil/ot-checksum-utils.c index bd787a3f86..beba888b19 100644 --- a/src/libotutil/ot-checksum-utils.c +++ b/src/libotutil/ot-checksum-utils.c @@ -22,10 +22,15 @@ #include "config.h" #include "otutil.h" +#if defined(HAVE_OPENSSL) +#include +#elif defined(HAVE_GNUTLS) +#include +#include +#endif #include - void ot_bin2hex (char *out_buf, const guint8 *inbuf, gsize len) { @@ -41,6 +46,119 @@ ot_bin2hex (char *out_buf, const guint8 *inbuf, gsize len) out_buf[j] = '\0'; } +/* I like to think of this as AbstractChecksumProxyFactoryBean. In homage to + * https://news.ycombinator.com/item?id=4549544 + * aka http://static.springsource.org/spring/docs/2.5.x/api/org/springframework/aop/framework/AbstractSingletonProxyFactoryBean.html + */ +typedef struct { + gboolean initialized; +#if defined(HAVE_OPENSSL) + EVP_MD_CTX *checksum; +#elif defined(HAVE_GNUTLS) + gnutls_hash_hd_t checksum; +#else + GChecksum *checksum; +#endif + guint digest_len; +} OtRealChecksum; + +G_STATIC_ASSERT (sizeof (OtChecksum) >= sizeof (OtRealChecksum)); + +void +ot_checksum_init (OtChecksum *checksum) +{ + OtRealChecksum *real = (OtRealChecksum*)checksum; + g_return_if_fail (!real->initialized); +#if defined(HAVE_OPENSSL) + real->checksum = EVP_MD_CTX_create (); + g_assert (real->checksum); + g_assert (EVP_DigestInit_ex (real->checksum, EVP_sha256 (), NULL)); + real->digest_len = EVP_MAX_MD_SIZE; +#elif defined(HAVE_GNUTLS) + g_assert (!gnutls_hash_init (&real->checksum, GNUTLS_DIG_SHA256)); + real->digest_len = gnutls_hash_get_len (GNUTLS_DIG_SHA256); +#else + real->checksum = g_checksum_new (G_CHECKSUM_SHA256); + real->digest_len = g_checksum_type_get_length (G_CHECKSUM_SHA256); +#endif + real->initialized = TRUE; +} + +void +ot_checksum_update (OtChecksum *checksum, + const guint8 *buf, + size_t len) +{ + OtRealChecksum *real = (OtRealChecksum*)checksum; + g_return_if_fail (real->initialized); +#if defined(HAVE_OPENSSL) + g_assert (EVP_DigestUpdate (real->checksum, buf, len)); +#elif defined(HAVE_GNUTLS) + g_assert (!gnutls_hash (real->checksum, buf, len)); +#else + g_checksum_update (real->checksum, buf, len); +#endif +} + +static void +ot_checksum_get_digest_internal (OtRealChecksum *real, + guint8 *buf, + size_t buflen) +{ + g_return_if_fail (real->initialized); + g_assert_cmpint (buflen, ==, _OSTREE_SHA256_DIGEST_LEN); +#if defined(HAVE_OPENSSL) + guint digest_len = buflen; + g_assert (EVP_DigestFinal_ex (real->checksum, digest_buf, &digest_len)); + g_assert_cmpint (digest_len, ==, buflen); +#elif defined(HAVE_GNUTLS) + gnutls_hash_output (real->checksum, buf); +#else + gsize digest_len = buflen; + g_checksum_get_digest (real->checksum, buf, &digest_len); + g_assert_cmpint (digest_len, ==, buflen); +#endif +} + +void +ot_checksum_get_digest (OtChecksum *checksum, + guint8 *buf, + size_t buflen) +{ + OtRealChecksum *real = (OtRealChecksum*)checksum; + ot_checksum_get_digest_internal (real, buf, buflen); + real->initialized = FALSE; +} + +void +ot_checksum_get_hexdigest (OtChecksum *checksum, + char *buf, + size_t buflen) +{ + OtRealChecksum *real = (OtRealChecksum*)checksum; + const guint digest_len = real->digest_len; + guint8 digest_buf[digest_len]; + ot_checksum_get_digest (checksum, digest_buf, digest_len); + ot_bin2hex (buf, (guint8*)digest_buf, digest_len); + real->initialized = FALSE; +} + +void +ot_checksum_clear (OtChecksum *checksum) +{ + OtRealChecksum *real = (OtRealChecksum*)checksum; + if (!real->initialized) + return; +#if defined(HAVE_OPENSSL) + EVP_MD_CTX_destroy (real->checksum); +#elif defined(HAVE_GNUTLS) + gnutls_hash_deinit (real->checksum, NULL); +#else + g_checksum_free (real->checksum); +#endif + real->initialized = FALSE; +} + guchar * ot_csum_from_gchecksum (GChecksum *checksum) { @@ -57,7 +175,7 @@ ot_gio_write_update_checksum (GOutputStream *out, gconstpointer data, gsize len, gsize *out_bytes_written, - GChecksum *checksum, + OtChecksum *checksum, GCancellable *cancellable, GError **error) { @@ -73,14 +191,14 @@ ot_gio_write_update_checksum (GOutputStream *out, } if (checksum) - g_checksum_update (checksum, data, len); + ot_checksum_update (checksum, data, len); return TRUE; } gboolean ot_gio_splice_update_checksum (GOutputStream *out, GInputStream *in, - GChecksum *checksum, + OtChecksum *checksum, GCancellable *cancellable, GError **error) { @@ -92,7 +210,7 @@ ot_gio_splice_update_checksum (GOutputStream *out, char buf[4096]; do { - if (!g_input_stream_read_all (in, buf, sizeof(buf), &bytes_read, cancellable, error)) + if (!g_input_stream_read_all (in, buf, sizeof (buf), &bytes_read, cancellable, error)) return FALSE; if (!ot_gio_write_update_checksum (out, buf, bytes_read, &bytes_written, checksum, cancellable, error)) @@ -119,12 +237,16 @@ ot_gio_splice_get_checksum (GOutputStream *out, GCancellable *cancellable, GError **error) { - g_autoptr(GChecksum) checksum = g_checksum_new (G_CHECKSUM_SHA256); + g_auto(OtChecksum) checksum = { 0, }; + ot_checksum_init (&checksum); - if (!ot_gio_splice_update_checksum (out, in, checksum, cancellable, error)) + if (!ot_gio_splice_update_checksum (out, in, &checksum, cancellable, error)) return FALSE; - g_autofree guchar *ret_csum = ot_csum_from_gchecksum (checksum); + guint8 digest[_OSTREE_SHA256_DIGEST_LEN]; + ot_checksum_get_digest (&checksum, digest, sizeof (digest)); + g_autofree guchar *ret_csum = g_malloc (sizeof (digest)); + memcpy (ret_csum, digest, sizeof (digest)); ot_transfer_out_value (out_csum, &ret_csum); return TRUE; } @@ -151,9 +273,12 @@ ot_checksum_file_at (int dfd, if (!ot_openat_read_stream (dfd, path, TRUE, &in, cancellable, error)) return FALSE; - g_autoptr(GChecksum) checksum = g_checksum_new (checksum_type); - if (!ot_gio_splice_update_checksum (NULL, in, checksum, cancellable, error)) + g_auto(OtChecksum) checksum = { 0, }; + ot_checksum_init (&checksum); + if (!ot_gio_splice_update_checksum (NULL, in, &checksum, cancellable, error)) return FALSE; - return g_strdup (g_checksum_get_string (checksum)); + char hexdigest[_OSTREE_SHA256_STRING_LEN+1]; + ot_checksum_get_hexdigest (&checksum, hexdigest, sizeof (hexdigest)); + return g_strdup (hexdigest); } diff --git a/src/libotutil/ot-checksum-utils.h b/src/libotutil/ot-checksum-utils.h index a0e72dbc0a..abf3c6db05 100644 --- a/src/libotutil/ot-checksum-utils.h +++ b/src/libotutil/ot-checksum-utils.h @@ -21,7 +21,7 @@ #pragma once -#include +#include "libglnx.h" G_BEGIN_DECLS @@ -29,11 +29,42 @@ void ot_bin2hex (char *out_buf, const guint8 *inbuf, gsize len); guchar *ot_csum_from_gchecksum (GChecksum *checksum); +struct OtChecksum { + gboolean initialized; + guint uints[2]; + gpointer data[2]; +}; +typedef struct OtChecksum OtChecksum; + +/* Same as OSTREE_SHA256_DIGEST_LEN, but this header can't depend on that */ +#define _OSTREE_SHA256_DIGEST_LEN (32) +#if defined(OSTREE_SHA256_DIGEST_LEN) && _OSTREE_SHA256_DIGEST_LEN != OSTREE_SHA256_DIGEST_LEN +#error Mismatched OSTREE_SHA256_DIGEST_LEN +#endif +/* See above */ +#define _OSTREE_SHA256_STRING_LEN (64) +#if defined(OSTREE_SHA256_STRING_LEN) && _OSTREE_SHA256_STRING_LEN != OSTREE_SHA256_STRING_LEN +#error Mismatched OSTREE_SHA256_STRING_LEN +#endif + +void ot_checksum_init (OtChecksum *checksum); +void ot_checksum_update (OtChecksum *checksum, + const guint8 *buf, + size_t len); +void ot_checksum_get_digest (OtChecksum *checksum, + guint8 *buf, + size_t buflen); +void ot_checksum_get_hexdigest (OtChecksum *checksum, + char *buf, + size_t buflen); +void ot_checksum_clear (OtChecksum *checksum); +G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(OtChecksum, ot_checksum_clear) + gboolean ot_gio_write_update_checksum (GOutputStream *out, gconstpointer data, gsize len, gsize *out_bytes_written, - GChecksum *checksum, + OtChecksum *checksum, GCancellable *cancellable, GError **error); @@ -45,7 +76,7 @@ gboolean ot_gio_splice_get_checksum (GOutputStream *out, gboolean ot_gio_splice_update_checksum (GOutputStream *out, GInputStream *in, - GChecksum *checksum, + OtChecksum *checksum, GCancellable *cancellable, GError **error);