mirror of
https://github.com/KeyKeeperApp/KeyKeeper.git
synced 2026-04-26 18:16:34 +03:00
fix HMAC in PassStoreContentChunk
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using System.Buffers.Binary;
|
using System.Buffers.Binary;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
@@ -37,7 +38,7 @@ public class PassStoreContentChunk
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
chunkLen = rd.ReadUInt16();
|
chunkLen = rd.ReadUInt16();
|
||||||
chunkLen = (chunkLen << 8) | rd.ReadByte();
|
chunkLen = chunkLen | (rd.ReadByte() << 16);
|
||||||
}
|
}
|
||||||
catch (EndOfStreamException)
|
catch (EndOfStreamException)
|
||||||
{
|
{
|
||||||
@@ -52,16 +53,28 @@ public class PassStoreContentChunk
|
|||||||
byte[] storedHmac = new byte[HMAC_SIZE];
|
byte[] storedHmac = new byte[HMAC_SIZE];
|
||||||
str.Read(storedHmac, 0, HMAC_SIZE);
|
str.Read(storedHmac, 0, HMAC_SIZE);
|
||||||
|
|
||||||
HMACSHA3_512 hmac = new(key);
|
SHA3_512 hasher = SHA3_512.Create();
|
||||||
hmac.TransformBlock(chunk, (int)str.Position, Math.Min(chunkLen, chunk.Length - (int)str.Position), null, 0);
|
byte[] innerKey = key.Select(x => (byte)(x ^ 0x36)).ToArray();
|
||||||
|
byte[] outerKey = key.Select(x => (byte)(x ^ 0x5c)).ToArray();
|
||||||
|
|
||||||
|
hasher.TransformBlock(innerKey, 0, innerKey.Length, null, 0);
|
||||||
|
Array.Fill<byte>(innerKey, 0); // erase key after use
|
||||||
|
|
||||||
|
hasher.TransformBlock(chunk, (int)str.Position, chunk.Length - (int)str.Position, null, 0);
|
||||||
|
|
||||||
byte[] encodedOrdinal = new byte[sizeof(int)];
|
byte[] encodedOrdinal = new byte[sizeof(int)];
|
||||||
BinaryPrimitives.WriteInt32LittleEndian(new Span<byte>(encodedOrdinal), chunkOrdinal);
|
BinaryPrimitives.WriteInt32LittleEndian(new Span<byte>(encodedOrdinal), chunkOrdinal);
|
||||||
hmac.TransformBlock(encodedOrdinal, 0, encodedOrdinal.Length, null, 0);
|
|
||||||
|
|
||||||
byte[] actualHmac = hmac.Hash!;
|
|
||||||
|
|
||||||
if (!storedHmac.Equals(actualHmac))
|
hasher.TransformFinalBlock(encodedOrdinal, 0, encodedOrdinal.Length);
|
||||||
|
byte[] innerHash = hasher.Hash!;
|
||||||
|
|
||||||
|
hasher = SHA3_512.Create();
|
||||||
|
hasher.TransformBlock(outerKey, 0, outerKey.Length, null, 0);
|
||||||
|
Array.Fill<byte>(outerKey, 0);
|
||||||
|
hasher.TransformFinalBlock(innerHash, 0, innerHash.Length);
|
||||||
|
byte[] actualHmac = hasher.Hash!;
|
||||||
|
|
||||||
|
if (!storedHmac.SequenceEqual(actualHmac))
|
||||||
{
|
{
|
||||||
throw PassStoreFileException.ContentHMACMismatch;
|
throw PassStoreFileException.ContentHMACMismatch;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user