/// <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; } }
/// <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); }
/// <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 }; }
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); }
public void DeserializeMissingId(KdbxVersion version, CompressionAlgorithm compression) { Assert.ThrowsException <KdbxParseException>( () => { new KdbxBinary( new XElement(KdbxBinary.RootName, Base64Uncompressed), new KdbxSerializationParameters(version) { Compression = compression } ); } ); }
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()); }
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"); }
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"); }