Exemplo n.º 1
0
        internal static DatabaseInfo ParseHeader(SpanStream io, byte[] compositeKey)
        {
            var header = io.Read <Header>();

            if (header.Signature1 != Magic1)
            {
                throw MakeInvalidFormatError($"primary file signature is invalid: {header.Signature1:x8}");
            }

            if (!Magic2.Contains(header.Signature2))
            {
                throw MakeInvalidFormatError($"secondary file signature is invalid: {header.Signature2:x8}");
            }

            if (header.MajorVersion != Version4)
            {
                throw MakeUnsupportedError($"Version {header.MajorVersion}.{header.MinorVersion}");
            }

            var info = ReadEncryptionInfo(ref io);

            var headerSize = io.Position;

            io.Rewind();
            var headerBytes = io.ReadBytes(headerSize);

            var computedHash = Crypto.Sha256(headerBytes);
            var storedHash   = io.ReadBytes(32);

            if (!Crypto.AreEqual(storedHash, computedHash))
            {
                throw MakeInvalidFormatError("Header hash doesn't match");
            }

            var storedHeaderMac = io.ReadBytes(32);

            var derivedKey = DeriveMasterKey(compositeKey, info.Kdf);

            var(encryptionKey, hmacKey) = Util.DeriveDatabaseKeys(derivedKey, info.Seed);

            var blockHmacKey      = Util.ComputeBlockHmacKey(hmacKey, ulong.MaxValue);
            var computedHeaderMac = Crypto.HmacSha256(blockHmacKey, headerBytes);

            if (!Crypto.AreEqual(storedHeaderMac, computedHeaderMac))
            {
                throw MakeInvalidFormatError("Header MAC doesn't match");
            }

            return(new DatabaseInfo(headerSize: io.Position,
                                    isCompressed: info.IsCompressed,
                                    cipher: info.Cipher,
                                    encryptionKey: encryptionKey,
                                    iv: info.Iv,
                                    hmacKey: hmacKey));
        }
Exemplo n.º 2
0
        public void TestReadOnlySpan()
        {
            var rnd = new Random();

            for (var c = 0; c < count; c++)
            {
                var memSize = rnd.Next(1, 10_000);
                var mem     = new byte[(memSize + 4) * writeRepeatCount];
                var answer  = new byte[memSize * writeRepeatCount];
                rnd.NextBytes(answer);
                var span1 = new SpanStream(mem);
                var span2 = new SpanStream(mem);

                for (var i = 0; i < writeRepeatCount; i++)
                {
                    var a = new Span <byte>(answer).Slice(memSize * i, memSize);
                    span1.Write(a);
                }

                // Ensure span is not zero
                var ac = 0;
                for (var wrc = 0; wrc < writeRepeatCount; wrc++)
                {
                    var r = span2.ReadBytes(memSize);

                    for (var i = 0; i < r.Length; i++)
                    {
                        Assert.Equal(answer[ac++], r[i]);
                    }
                }

                Assert.Throws <ArgumentException>(() =>
                {
                    var s = new SpanStream(mem);
                    s.Write(new Span <byte>(new byte[mem.Length + 1]));
                });
            }
        }