summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibCrypto
diff options
context:
space:
mode:
authorkleines Filmröllchen <filmroellchen@serenityos.org>2023-05-18 15:58:57 +0200
committerJelle Raaijmakers <jelle@gmta.nl>2023-05-18 22:23:15 +0200
commit70ab4566f390ba85175147579b7f52cbc4e16b00 (patch)
tree060d72b15cfe34d38d698dbfadea840011f5eab8 /Userland/Libraries/LibCrypto
parentdaf50ed88521dc6e61cd80e57dc00f6a3d3d13bf (diff)
downloadserenity-70ab4566f390ba85175147579b7f52cbc4e16b00.zip
LibCrypto: Add a checksumming stream wrapper
This generic stream wrapper performs checksum calculations on all data passed through it for reading or writing, and is therefore convenient for calculating checksums while performing normal data input/output, as well as computing streaming checksums on non-seekable streams.
Diffstat (limited to 'Userland/Libraries/LibCrypto')
-rw-r--r--Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h81
1 files changed, 81 insertions, 0 deletions
diff --git a/Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h b/Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h
new file mode 100644
index 0000000000..5c71d00d29
--- /dev/null
+++ b/Userland/Libraries/LibCrypto/Checksum/ChecksummingStream.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/ByteBuffer.h>
+#include <AK/Concepts.h>
+#include <AK/MaybeOwned.h>
+#include <AK/Stream.h>
+#include <LibCrypto/Checksum/ChecksumFunction.h>
+
+namespace Crypto::Checksum {
+
+// A stream wrapper type which passes all read and written data through a checksum function.
+template<typename ChecksumFunctionType, typename ChecksumType = typename ChecksumFunctionType::ChecksumType>
+requires(
+ IsBaseOf<ChecksumFunction<ChecksumType>, ChecksumFunctionType>,
+ // Require checksum function to be constructible without arguments, since we have no initial data.
+ requires() {
+ ChecksumFunctionType {};
+ })
+class ChecksummingStream : public Stream {
+public:
+ virtual ~ChecksummingStream() = default;
+
+ ChecksummingStream(MaybeOwned<Stream> stream)
+ : m_stream(move(stream))
+ {
+ }
+
+ virtual ErrorOr<Bytes> read_some(Bytes bytes) override
+ {
+ auto const written_bytes = TRY(m_stream->read_some(bytes));
+ update(written_bytes);
+ return written_bytes;
+ }
+
+ virtual ErrorOr<void> read_until_filled(Bytes bytes) override
+ {
+ TRY(m_stream->read_until_filled(bytes));
+ update(bytes);
+ return {};
+ }
+
+ virtual ErrorOr<size_t> write_some(ReadonlyBytes bytes) override
+ {
+ auto bytes_written = TRY(m_stream->write_some(bytes));
+ // Only update with the bytes that were actually written
+ update(bytes.trim(bytes_written));
+ return bytes_written;
+ }
+
+ virtual ErrorOr<void> write_until_depleted(ReadonlyBytes bytes) override
+ {
+ update(bytes);
+ return m_stream->write_until_depleted(bytes);
+ }
+
+ virtual bool is_eof() const override { return m_stream->is_eof(); }
+ virtual bool is_open() const override { return m_stream->is_open(); }
+ virtual void close() override { m_stream->close(); }
+
+ ChecksumType digest()
+ {
+ return m_checksum.digest();
+ }
+
+private:
+ ALWAYS_INLINE void update(ReadonlyBytes bytes)
+ {
+ m_checksum.update(bytes);
+ }
+
+ MaybeOwned<Stream> m_stream;
+ ChecksumFunctionType m_checksum {};
+};
+
+}