示例#1
0
        /// <summary>
        /// Configures the basic parameters based on the version being used.
        /// </summary>
        /// <param name="version">The current parser version.</param>
        public KdbxSerializationParameters(KdbxVersion version)
        {
            this.version = version;

            // Update parameters based on the parser version.
            switch (Version)
            {
            case KdbxVersion.Three:
                HeaderFieldSizeBytes          = 2;
                UseExtensibleKdf              = false;
                UseHmacBlocks                 = false;
                UseLegacyHashedBlocks         = true;
                UseInnerHeader                = false;
                UseXmlHeaderAuthentication    = true;
                UseInlineHeaderAuthentication = false;
                UseBase64DateTimeEncoding     = false;
                BinariesInHeader              = false;
                break;

            // Default to modern (Four) behavior
            default:
                HeaderFieldSizeBytes          = 4;
                UseExtensibleKdf              = true;
                UseHmacBlocks                 = true;
                UseLegacyHashedBlocks         = false;
                UseInnerHeader                = true;
                UseXmlHeaderAuthentication    = false;
                UseInlineHeaderAuthentication = true;
                UseBase64DateTimeEncoding     = true;
                BinariesInHeader              = true;
                break;
            }
        }
示例#2
0
        /// <summary>
        /// Determines whether the specified version is within the range
        /// of this attribute.
        /// </summary>
        /// <param name="version">The version to test.</param>
        /// <returns>Whether <paramref name="version"/> is within
        /// <see cref="Max"/> and <see cref="Min"/>.</returns>
        public bool Supports(KdbxVersion version)
        {
            if (Min != KdbxVersion.Unspecified && Min > version)
            {
                return(false);
            }

            if (Max != KdbxVersion.Unspecified && Max < version)
            {
                return(false);
            }

            return(true);
        }
示例#3
0
        /// <summary>
        /// Ensures the writer's serialization settings are correct for the given user preferences.
        /// </summary>
        /// <param name="cipher">The algorithm to use for encrypting the database.</param>
        /// <param name="rngAlgorithm">The random number generator used for String protection.</param>
        /// <param name="compression">The document compression algorithm.</param>
        /// <param name="kdfParams">Recipe for transforming the raw key. This will be reseeded.</param>
        private void SeedHeaderData(
            EncryptionAlgorithm cipher,
            RngAlgorithm rngAlgorithm,
            CompressionAlgorithm compression,
            KdfParameters kdfParams
            )
        {
            if (kdfParams == null)
            {
                throw new ArgumentNullException(nameof(kdfParams));
            }

            KdbxVersion version = KdbxVersion.Three;

            if (cipher == EncryptionAlgorithm.ChaCha20 || rngAlgorithm == RngAlgorithm.ChaCha20 ||
                !kdfParams.Uuid.Equals(AesParameters.AesUuid))
            {
                DebugHelper.Trace("Using KDBX4 for serialization due to header parameters");
                version = KdbxVersion.Four;
            }

            this.parameters = new KdbxSerializationParameters(version)
            {
                Compression = compression
            };

            // "Stream start bytes" are random data encrypted at the beginning
            // of the KDBX data block. They have been superceded by HMAC authentication.
            IBuffer streamStartBytes;

            if (this.parameters.UseHmacBlocks)
            {
                streamStartBytes = new byte[0].AsBuffer();
            }
            else
            {
                streamStartBytes = CryptographicBuffer.GenerateRandom(32);
            }

            HeaderData = new KdbxHeaderData(KdbxHeaderData.Mode.Write)
            {
                Cipher               = cipher, // This will automatically set EncryptionIV
                Compression          = compression,
                MasterSeed           = CryptographicBuffer.GenerateRandom(32),
                KdfParameters        = kdfParams.Reseed(),
                StreamStartBytes     = streamStartBytes,
                InnerRandomStreamKey = CryptographicBuffer.GenerateRandom(32).ToArray(),
                InnerRandomStream    = rngAlgorithm
            };
        }
示例#4
0
        public void DeserializeNoValue(KdbxVersion version, CompressionAlgorithm compression)
        {
            KdbxBinary binary = new KdbxBinary(
                new XElement(KdbxBinary.RootName, "",
                             new XAttribute("ID", 1)
                             ),
                new KdbxSerializationParameters(version)
            {
                Compression = compression
            }
                );

            Assert.AreEqual(1, binary.Id);
            Assert.AreEqual(0, binary.BinaryData.GetClearData().Length);
        }
示例#5
0
 public void DeserializeMissingId(KdbxVersion version, CompressionAlgorithm compression)
 {
     Assert.ThrowsException <KdbxParseException>(
         () =>
     {
         new KdbxBinary(
             new XElement(KdbxBinary.RootName, Base64Uncompressed),
             new KdbxSerializationParameters(version)
         {
             Compression = compression
         }
             );
     }
         );
 }
示例#6
0
        public void DeserializeUncompressed(KdbxVersion version, CompressionAlgorithm compression)
        {
            KdbxBinary binary = new KdbxBinary(
                new XElement(KdbxBinary.RootName, Base64Uncompressed,
                             new XAttribute("ID", 1)
                             ),
                new KdbxSerializationParameters(version)
            {
                Compression = compression
            }
                );

            Assert.AreEqual(1, binary.Id);
            ValidateBytes(binary.BinaryData.GetClearData());
        }
示例#7
0
        public void SerializeNoValueCompressed(KdbxVersion version, bool protect)
        {
            ProtectedBinary bin        = new ProtectedBinary(new byte[0], protect);
            KdbxBinary      binary     = new KdbxBinary(1, bin);
            XElement        serialized = binary.ToXml(
                new MockRng(),
                new KdbxSerializationParameters(version)
            {
                Compression = CompressionAlgorithm.GZip
            }
                );

            Assert.AreEqual(binary.Id.ToString(), serialized.Attribute("ID").Value, "ID should serialize properly");
            Assert.AreEqual("True", serialized.Attribute("Compressed").Value, "Compressed attribute should not be set");
            Assert.AreEqual("", serialized.Value, "XML value should serialize properly");
        }
示例#8
0
        public void SerializeUncompressed(KdbxVersion version, bool protect)
        {
            ProtectedBinary bin        = new ProtectedBinary(ExpectedBytes, protect);
            KdbxBinary      binary     = new KdbxBinary(1, bin);
            XElement        serialized = binary.ToXml(
                new MockRng(),
                new KdbxSerializationParameters(version)
            {
                Compression = CompressionAlgorithm.None
            }
                );

            Assert.AreEqual(binary.Id.ToString(), serialized.Attribute("ID").Value, "ID should serialize properly");
            Assert.IsNull(serialized.Attribute("Compressed"), "Compressed attribute should not be set");
            Assert.AreEqual(Base64Uncompressed, serialized.Value, "XML value should serialize properly");
        }