diff --git a/ModernKeePassLib.Test/Cryptography/Cipher/StandardAesEngineTests.cs b/ModernKeePassLib.Test/Cryptography/Cipher/StandardAesEngineTests.cs index 50580cd..cb78604 100644 --- a/ModernKeePassLib.Test/Cryptography/Cipher/StandardAesEngineTests.cs +++ b/ModernKeePassLib.Test/Cryptography/Cipher/StandardAesEngineTests.cs @@ -1,6 +1,9 @@ using System; using System.IO; - +using System.Security; +using System.Text; +using ModernKeePassLib.Serialization; +using ModernKeePassLib.Utility; #if KeePassLib using KeePassLib.Cryptography.Cipher; #else @@ -8,58 +11,74 @@ using ModernKeePassLib.Cryptography.Cipher; #endif using NUnit.Framework; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; namespace ModernKeePassLib.Test.Shared.Cryptography.Cipher { - [TestFixture ()] - public class StandardAesEngineTests - { - [Test ()] - public void TestEncryptStream () + [TestFixture()] + public class StandardAesEngineTests { - // Test vector (official ECB test vector #356) - var pbIV = new byte[16]; - var pbTestKey = new byte[32]; - var pbTestData = new byte[16]; - var pbReferenceCT = new byte[16] { - 0x75, 0xD1, 0x1B, 0x0E, 0x3A, 0x68, 0xC4, 0x22, - 0x3D, 0x88, 0xDB, 0xF0, 0x17, 0x97, 0x7D, 0xD7 + // Test vector (official ECB test vector #356) + private byte[] pbReferenceCT = new byte[16] { + 0x75, 0xD1, 0x1B, 0x0E, 0x3A, 0x68, 0xC4, 0x22, + 0x3D, 0x88, 0xDB, 0xF0, 0x17, 0x97, 0x7D, 0xD7 }; + [Test] + public void TestEncryptStream() + { + byte[] pbIV = new byte[16]; + byte[] pbTestKey = new byte[32]; + byte[] pbTestData = new byte[16]; + pbTestData[0] = 0x04; - pbTestData[0] = 0x04; + var outStream = new MemoryStream(new byte[16]); + var aes = new StandardAesEngine(); + var inStream = aes.EncryptStream(outStream, pbTestKey, pbIV); + new BinaryWriter(inStream).Write(pbTestData); + //Assert.That(outStream.Position, Is.EqualTo(16)); + outStream.Position = 0; + var outBytes = new BinaryReaderEx(outStream, Encoding.UTF8, string.Empty).ReadBytes(16); + Assert.That(outBytes, Is.EqualTo(pbReferenceCT)); + } - var outStream = new MemoryStream (new byte[16]); - var aes = new StandardAesEngine (); - var inStream = aes.EncryptStream (outStream, pbTestKey, pbIV); - new BinaryWriter (inStream).Write (pbTestData); - Assert.That (outStream.Position, Is.EqualTo (16)); - outStream.Position = 0; - var outBytes = new BinaryReader (outStream).ReadBytes (16); - Assert.That(outBytes, Is.EqualTo (pbReferenceCT)); - } - - [Test ()] - public void TestDecryptStream () + [Test] + public void TestDecryptStream() { - // Test vector (official ECB test vector #356) - var pbIV = new byte[16]; - var pbTestKey = new byte[32]; - var pbTestData = new byte[16]; - var pbReferenceCT = new byte[16] { - 0x75, 0xD1, 0x1B, 0x0E, 0x3A, 0x68, 0xC4, 0x22, - 0x3D, 0x88, 0xDB, 0xF0, 0x17, 0x97, 0x7D, 0xD7 - }; + byte[] pbIV = new byte[16]; + byte[] pbTestKey = new byte[32]; + byte[] pbTestData = new byte[16]; + pbTestData[0] = 0x04; - pbTestData[0] = 0x04; + // Possible Mono Bug? This only works with size >= 48 + var inStream = new MemoryStream(new byte[32]); + inStream.Write(pbReferenceCT, 0, pbReferenceCT.Length); + inStream.Position = 0; + var aes = new StandardAesEngine(); + var outStream = aes.DecryptStream(inStream, pbTestKey, pbIV); + var outBytes = new BinaryReaderEx(outStream, Encoding.UTF8, string.Empty).ReadBytes(16); + Assert.That(outBytes, Is.EqualTo(pbTestData)); + } - // Possible Mono Bug? This only works with size >= 48 - var inStream = new MemoryStream (new byte[48]); - inStream.Write (pbReferenceCT, 0, pbReferenceCT.Length); - inStream.Position = 0; - var aes = new StandardAesEngine (); - var outStream = aes.DecryptStream (inStream, pbTestKey, pbIV); - var outBytes = new BinaryReader (outStream).ReadBytes (16); - Assert.That(outBytes, Is.EqualTo (pbTestData)); + [Test] + public void TestBouncyCastleAes() + { + byte[] pbIV = new byte[16]; + byte[] pbTestKey = new byte[32]; + byte[] pbTestData = new byte[16]; + /*int i; + for (i = 0; i < 16; ++i) pbIV[i] = 0; + for (i = 0; i < 32; ++i) pbTestKey[i] = 0; + for (i = 0; i < 16; ++i) pbTestData[i] = 0;*/ + pbTestData[0] = 0x04; + + var aesEngine = new AesEngine(); + //var parametersWithIv = new ParametersWithIV(new KeyParameter(pbTestKey), pbIV); + aesEngine.Init(true, new KeyParameter(pbTestKey)); + Assert.That(aesEngine.GetBlockSize(), Is.EqualTo(pbTestData.Length)); + aesEngine.ProcessBlock(pbTestData, 0, pbTestData, 0); + //Assert.That(MemUtil.ArraysEqual(pbTestData, pbReferenceCT), Is.False); + Assert.That(pbTestData, Is.EqualTo(pbReferenceCT)); + } } - } } diff --git a/ModernKeePassLib/Cryptography/CryptoUtil.cs b/ModernKeePassLib/Cryptography/CryptoUtil.cs index a67e510..1e690ee 100644 --- a/ModernKeePassLib/Cryptography/CryptoUtil.cs +++ b/ModernKeePassLib/Cryptography/CryptoUtil.cs @@ -33,6 +33,7 @@ using System.Security.Cryptography; using ModernKeePassLib.Native; using ModernKeePassLib.Utility; +using Org.BouncyCastle.Crypto.Digests; namespace ModernKeePassLib.Cryptography { @@ -57,9 +58,13 @@ namespace ModernKeePassLib.Cryptography byte[] pbHash; #if ModernKeePassLib - var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256) + /*var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256) .HashData(CryptographicBuffer.CreateFromByteArray(pbData)); - CryptographicBuffer.CopyToByteArray(h, out pbHash); + CryptographicBuffer.CopyToByteArray(h, out pbHash);*/ + pbHash = new byte[32]; + var h = new Sha256Digest(); + h.BlockUpdate(pbData, iOffset, cbCount); + h.DoFinal(pbHash, iOffset); #else using(SHA256Managed h = new SHA256Managed()) { @@ -96,16 +101,20 @@ namespace ModernKeePassLib.Cryptography else { #if ModernKeePassLib - var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512) + /*var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512) .HashData(CryptographicBuffer.CreateFromByteArray(pbIn)); - CryptographicBuffer.CopyToByteArray(h, out pbHash); + CryptographicBuffer.CopyToByteArray(h, out pbHash);*/ + pbHash = new byte[64]; + var h = new Sha512Digest(); + h.BlockUpdate(pbIn, iInOffset, cbIn); + h.DoFinal(pbHash, iInOffset); #else using(SHA512Managed h = new SHA512Managed()) { pbHash = h.ComputeHash(pbIn, iInOffset, cbIn); } #endif - } + } if(cbOut == pbHash.Length) return pbHash; diff --git a/ModernKeePassLib/Cryptography/Hash/DigestManaged.cs b/ModernKeePassLib/Cryptography/Hash/DigestManaged.cs new file mode 100644 index 0000000..bddb984 --- /dev/null +++ b/ModernKeePassLib/Cryptography/Hash/DigestManaged.cs @@ -0,0 +1,31 @@ +using System; +using Org.BouncyCastle.Crypto; + +namespace ModernKeePassLib.Cryptography.Hash +{ + public abstract class DigestManaged: IDisposable + { + protected IDigest Hash; + + public byte[] ComputeHash(byte[] value) + { + return ComputeHash(value, 0, value.Length); + } + + public byte[] ComputeHash(byte[] value, int offset, int length) + { + if (value == null) throw new ArgumentNullException(nameof(value)); + + byte[] resBuf = new byte[Hash.GetByteLength()]; + Hash.BlockUpdate(value, 0, length); + Hash.DoFinal(resBuf, 0); + + return resBuf; + } + + public void Dispose() + { + Hash.Reset(); + } + } +} diff --git a/ModernKeePassLib/Cryptography/Hash/SHA256Managed.cs b/ModernKeePassLib/Cryptography/Hash/SHA256Managed.cs new file mode 100644 index 0000000..55d1cbd --- /dev/null +++ b/ModernKeePassLib/Cryptography/Hash/SHA256Managed.cs @@ -0,0 +1,12 @@ +using Org.BouncyCastle.Crypto.Digests; + +namespace ModernKeePassLib.Cryptography.Hash +{ + public class SHA256Managed : DigestManaged + { + public SHA256Managed() + { + Hash = new Sha256Digest(); + } + } +} diff --git a/ModernKeePassLib/Cryptography/Hash/SHA512Managed.cs b/ModernKeePassLib/Cryptography/Hash/SHA512Managed.cs new file mode 100644 index 0000000..d98ba77 --- /dev/null +++ b/ModernKeePassLib/Cryptography/Hash/SHA512Managed.cs @@ -0,0 +1,12 @@ +using Org.BouncyCastle.Crypto.Digests; + +namespace ModernKeePassLib.Cryptography.Hash +{ + public class SHA512Managed: DigestManaged + { + public SHA512Managed() + { + Hash = new Sha512Digest(); + } + } +} diff --git a/ModernKeePassLib/Cryptography/HashingStreamEx.cs b/ModernKeePassLib/Cryptography/HashingStreamEx.cs index 790958b..bb1ca6d 100644 --- a/ModernKeePassLib/Cryptography/HashingStreamEx.cs +++ b/ModernKeePassLib/Cryptography/HashingStreamEx.cs @@ -185,7 +185,7 @@ namespace ModernKeePassLib.Cryptography if((m_hash != null) && (nRead > 0)) #if ModernKeePassLib - m_hash.BlockUpdate(pbBuffer, nOffset, nRead); + m_hash.BlockUpdate(pbBuffer, nOffset, nRead); #else m_hash.TransformBlock(pbBuffer, nOffset, nRead, pbBuffer, nOffset); #endif @@ -208,7 +208,7 @@ namespace ModernKeePassLib.Cryptography if((m_hash != null) && (nCount > 0)) #if ModernKeePassLib - m_hash.BlockUpdate(pbBuffer, nOffset, nCount); + m_hash.BlockUpdate(pbBuffer, nOffset, nCount); #else m_hash.TransformBlock(pbBuffer, nOffset, nCount, pbBuffer, nOffset); #endif diff --git a/ModernKeePassLib/Cryptography/SelfTest.cs b/ModernKeePassLib/Cryptography/SelfTest.cs index 22206d4..420c02a 100644 --- a/ModernKeePassLib/Cryptography/SelfTest.cs +++ b/ModernKeePassLib/Cryptography/SelfTest.cs @@ -19,31 +19,28 @@ using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Globalization; +using System.IO; using System.Security; -#if ModernKeePassLib -using Windows.Security.Cryptography; +using System.Text; + +#if ModernKeePassLib || KeePassUAP +using Org.BouncyCastle.Crypto; +using Org.BouncyCastle.Crypto.Engines; +using Org.BouncyCastle.Crypto.Parameters; #else using System.Security.Cryptography; #endif -using System.Text; -using System.Globalization; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices.WindowsRuntime; -using Windows.Security.Cryptography.Core; + using ModernKeePassLib.Cryptography.Cipher; using ModernKeePassLib.Cryptography.Hash; using ModernKeePassLib.Cryptography.KeyDerivation; using ModernKeePassLib.Keys; using ModernKeePassLib.Native; -using ModernKeePassLib.Utility; using ModernKeePassLib.Resources; using ModernKeePassLib.Security; -using Org.BouncyCastle.Crypto.Digests; -using Org.BouncyCastle.Crypto.Engines; -using Org.BouncyCastle.Crypto.Macs; -using Org.BouncyCastle.Crypto.Parameters; -using KdfParameters = Org.BouncyCastle.Crypto.Parameters.KdfParameters; +using ModernKeePassLib.Utility; namespace ModernKeePassLib.Cryptography { @@ -70,9 +67,8 @@ namespace ModernKeePassLib.Cryptography TestHmac(); TestKeyTransform(r); -#if !ModernKeePassLib TestNativeKeyTransform(r); -#endif + TestHmacOtp(); TestProtectedObjects(r); @@ -99,14 +95,7 @@ namespace ModernKeePassLib.Cryptography } #endif -#if ModernKeePassLib - try - { - HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256); - } -#else try { using(SHA256Managed h = new SHA256Managed()) { } } -#endif catch(Exception exSha256) { throw new SecurityException("SHA-256: " + exSha256.Message); @@ -771,10 +760,9 @@ namespace ModernKeePassLib.Cryptography #endif } -#if !ModernKeePassLib - private static void TestNativeKeyTransform() + private static void TestNativeKeyTransform(Random r) { -#if DEBUG +#if !ModernKeePassLib && DEBUG byte[] pbOrgKey = CryptoRandom.Instance.GetRandomBytes(32); byte[] pbSeed = CryptoRandom.Instance.GetRandomBytes(32); ulong uRounds = (ulong)r.Next(1, 0x3FFF); @@ -793,7 +781,6 @@ namespace ModernKeePassLib.Cryptography throw new SecurityException("AES-KDF-2"); #endif } -#endif private static void TestMemUtil(Random r) { diff --git a/ModernKeePassLib/ModernKeePassLib.csproj b/ModernKeePassLib/ModernKeePassLib.csproj index f3b3ce0..d19ee85 100644 --- a/ModernKeePassLib/ModernKeePassLib.csproj +++ b/ModernKeePassLib/ModernKeePassLib.csproj @@ -61,7 +61,10 @@ + + + diff --git a/ModernKeePassLib/Serialization/KdbxFile.Read.Streamed.cs b/ModernKeePassLib/Serialization/KdbxFile.Read.Streamed.cs index 6da3604..1478554 100644 --- a/ModernKeePassLib/Serialization/KdbxFile.Read.Streamed.cs +++ b/ModernKeePassLib/Serialization/KdbxFile.Read.Streamed.cs @@ -22,10 +22,12 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Text; -using System.Security; -using System.Drawing; using System.Xml; +#if !ModernKeePassLib && !KeePassUAP +using System.Drawing; +#endif + using ModernKeePassLib; using ModernKeePassLib.Collections; using ModernKeePassLib.Cryptography; @@ -107,15 +109,15 @@ namespace ModernKeePassLib.Serialization xrs.IgnoreProcessingInstructions = true; xrs.IgnoreWhitespace = true; -#if !ModernKeePassLib - // these are default values, so no need to set them -#if !KeePassRT +#if ModernKeePassLib || KeePassUAP + xrs.DtdProcessing = DtdProcessing.Prohibit; +#else #if !KeePassLibSD - xrs.ProhibitDtd = true; + // Also see PrepMonoDev.sh script + xrs.ProhibitDtd = true; // Obsolete in .NET 4, but still there + // xrs.DtdProcessing = DtdProcessing.Prohibit; // .NET 4 only #endif xrs.ValidationType = ValidationType.None; -#endif - #endif return xrs;