aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpukkamustard <pukkamustard@posteo.net>2020-11-17 18:54:12 +0100
committerpukkamustard <pukkamustard@posteo.net>2020-11-17 18:54:12 +0100
commita897d1443dcf141f446ad6aa7c1d9e5ba1e94634 (patch)
tree30d989d304a76947128a502cc1151ebe37c21cbd
parent405dc1406e437042d68568618a0a01c323aa7333 (diff)
ERIS.Decode: detect corruption
-rw-r--r--lib/eris/decode.ex26
-rw-r--r--test/eris_test.exs8
2 files changed, 31 insertions, 3 deletions
diff --git a/lib/eris/decode.ex b/lib/eris/decode.ex
index 6d26cf3..6691e24 100644
--- a/lib/eris/decode.ex
+++ b/lib/eris/decode.ex
@@ -56,6 +56,16 @@ defmodule ERIS.Decode do
)
end
+ defp get_block(block_storage, reference) do
+ with {:ok, block} <- BlockStorage.get(block_storage, reference) do
+ if Crypto.blake2b(block) == reference do
+ {:ok, block}
+ else
+ {:error, :corrupt_block}
+ end
+ end
+ end
+
defp decode_block(block, key) do
block
|> Crypto.chacha20(key: key)
@@ -80,7 +90,7 @@ defmodule ERIS.Decode do
"""
def down(%__MODULE__{level: level, right: [{reference, key} | tail]} = node, block_storage)
when level > 1 do
- with {:ok, block} <- BlockStorage.get(block_storage, reference) do
+ with {:ok, block} <- get_block(block_storage, reference) do
%__MODULE__{
level: level - 1,
left: [],
@@ -104,6 +114,16 @@ defmodule ERIS.Decode do
def up(%__MODULE__{up: up}), do: up
end
+ defp get_block(block_storage, reference) do
+ with {:ok, block} <- BlockStorage.get(block_storage, reference) do
+ if Crypto.blake2b(block) == reference do
+ {:ok, block}
+ else
+ {:error, :corrupt_block}
+ end
+ end
+ end
+
# Traverse the tree and emit block. This implements a depth-first search using
# the Zipper nodes.
@@ -116,7 +136,7 @@ defmodule ERIS.Decode do
block_storage,
block_size
) do
- with {:ok, block} <- BlockStorage.get(block_storage, reference),
+ with {:ok, block} <- get_block(block_storage, reference),
decrypted <- Crypto.chacha20(block, key: key),
{:ok, unpadded} <- Crypto.unpad(decrypted, block_size: block_size) do
{[unpadded], Node.right(node)}
@@ -129,7 +149,7 @@ defmodule ERIS.Decode do
block_storage,
_block_size
) do
- with {:ok, block} <- BlockStorage.get(block_storage, reference) do
+ with {:ok, block} <- get_block(block_storage, reference) do
{[
block
|> Crypto.chacha20(key: key)
diff --git a/test/eris_test.exs b/test/eris_test.exs
index 3976ff5..6bedda3 100644
--- a/test/eris_test.exs
+++ b/test/eris_test.exs
@@ -74,4 +74,12 @@ defmodule ERISTest do
assert {:error, :invalid_padding} = ERIS.decode(read_capability, blocks)
end
end
+
+ test "detect corruption" do
+ with {read_capability, blocks} <- ERIS.encode("Hello!", %{}),
+ corrupted_blocks <-
+ Map.replace(blocks, Map.keys(blocks) |> List.first(), <<0::8192>>) do
+ assert {:error, :corrupt_block} = ERIS.decode(read_capability, corrupted_blocks)
+ end
+ end
end