From 84e7afc819fddecff9fc516648043fb4e23abb31 Mon Sep 17 00:00:00 2001 From: bg45 Date: Sun, 22 Oct 2017 06:18:57 -0400 Subject: [PATCH] WIP - Implementing HMAC with BouncyCastle --- ModernKeePass/ModernKeePass.csproj | 4 +-- ModernKeePass/packages.config | 2 +- ModernKeePassLib.Test/Utility/GfxUtilTests.cs | 4 +-- ModernKeePassLib/Cryptography/CryptoUtil.cs | 32 ++++++----------- .../Cryptography/Hash/HMACSHA256.cs | 35 +++++++++++++++++++ ModernKeePassLib/Cryptography/SelfTest.cs | 2 +- ModernKeePassLib/Keys/KcpPassword.cs | 6 ++-- ModernKeePassLib/ModernKeePassLib.csproj | 1 + ModernKeePassLib/Serialization/KdbxFile.cs | 7 +--- 9 files changed, 56 insertions(+), 37 deletions(-) create mode 100644 ModernKeePassLib/Cryptography/Hash/HMACSHA256.cs diff --git a/ModernKeePass/ModernKeePass.csproj b/ModernKeePass/ModernKeePass.csproj index 6fb6a1c..a2e3cbf 100644 --- a/ModernKeePass/ModernKeePass.csproj +++ b/ModernKeePass/ModernKeePass.csproj @@ -253,8 +253,8 @@ ..\packages\Microsoft.Toolkit.Uwp.Notifications.2.0.0\lib\dotnet\Microsoft.Toolkit.Uwp.Notifications.dll True - - ..\packages\ModernKeePassLib.2.28.4000\lib\netstandard1.2\ModernKeePassLib.dll + + ..\packages\ModernKeePassLib.2.37.1000\lib\netstandard1.2\ModernKeePassLib.dll True diff --git a/ModernKeePass/packages.config b/ModernKeePass/packages.config index a80ea94..78c501c 100644 --- a/ModernKeePass/packages.config +++ b/ModernKeePass/packages.config @@ -3,7 +3,7 @@ - + diff --git a/ModernKeePassLib.Test/Utility/GfxUtilTests.cs b/ModernKeePassLib.Test/Utility/GfxUtilTests.cs index 9977178..9e3bc6e 100644 --- a/ModernKeePassLib.Test/Utility/GfxUtilTests.cs +++ b/ModernKeePassLib.Test/Utility/GfxUtilTests.cs @@ -21,10 +21,10 @@ namespace ModernKeePassLib.Test.Shared.Utility "QMdny4VogAAAABJRU5ErkJggg=="; [Test ()] - public async void TestLoadImage () + public void TestLoadImage () { var testData = Convert.FromBase64String (testImageData); - var image = await GfxUtil.LoadImage (testData); + var image = GfxUtil.ScaleImage(testData, 16, 16).GetAwaiter().GetResult(); Assert.That (image.Width, Is.EqualTo (16)); Assert.That (image.Height, Is.EqualTo (16)); } diff --git a/ModernKeePassLib/Cryptography/CryptoUtil.cs b/ModernKeePassLib/Cryptography/CryptoUtil.cs index 448965e..62b5eed 100644 --- a/ModernKeePassLib/Cryptography/CryptoUtil.cs +++ b/ModernKeePassLib/Cryptography/CryptoUtil.cs @@ -25,8 +25,10 @@ using System.Text; using Windows.Security.Cryptography; using Windows.Security.Cryptography.Core; +using ModernKeePassLib.Cryptography.Hash; using ModernKeePassLib.Native; using ModernKeePassLib.Utility; +using Org.BouncyCastle.Asn1.Pkcs; namespace ModernKeePassLib.Cryptography { @@ -54,15 +56,15 @@ namespace ModernKeePassLib.Cryptography var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha256).CreateHash(); CryptographicBuffer.CopyToByteArray(h.GetValueAndReset(), out pbHash); #else - using(SHA256Managed h = new SHA256Managed()) + using(SHA256Managed h = new SHA256Managed()) { pbHash = h.ComputeHash(pbData, iOffset, cbCount); } #endif #if DEBUG - // Ensure the data has not been modified - Debug.Assert(MemUtil.ArraysEqual(pbData, pbCopy)); + // Ensure the data has not been modified + Debug.Assert(MemUtil.ArraysEqual(pbData, pbCopy)); Debug.Assert((pbHash != null) && (pbHash.Length == 32)); byte[] pbZero = new byte[32]; @@ -92,12 +94,12 @@ namespace ModernKeePassLib.Cryptography var h = HashAlgorithmProvider.OpenAlgorithm(HashAlgorithmNames.Sha512).CreateHash(); CryptographicBuffer.CopyToByteArray(h.GetValueAndReset(), out pbHash); #else - using(SHA512Managed h = new SHA512Managed()) + using(SHA512Managed h = new SHA512Managed()) { pbHash = h.ComputeHash(pbIn, iInOffset, cbIn); } #endif - } + } if(cbOut == pbHash.Length) return pbHash; @@ -111,20 +113,7 @@ namespace ModernKeePassLib.Cryptography while(iPos < cbOut) { Debug.Assert(pbHash.Length == 64); - byte[] pbR = MemUtil.UInt64ToBytes(r); -#if ModernKeePassLib - var h = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256).CreateHash(CryptographicBuffer.CreateFromByteArray(pbR)); - byte[] pbPart; - CryptographicBuffer.CopyToByteArray(h.GetValueAndReset(), out pbPart); - int cbCopy = Math.Min(cbOut - iPos, pbPart.Length); - Debug.Assert(cbCopy > 0); - Array.Copy(pbPart, 0, pbRet, iPos, cbCopy); - iPos += cbCopy; - ++r; - - MemUtil.ZeroByteArray(pbPart); -#else - using (HMACSHA256 h = new HMACSHA256(pbHash)) + using(HMACSHA256 h = new HMACSHA256(pbHash)) { byte[] pbR = MemUtil.UInt64ToBytes(r); byte[] pbPart = h.ComputeHash(pbR); @@ -138,7 +127,6 @@ namespace ModernKeePassLib.Cryptography MemUtil.ZeroByteArray(pbPart); } -#endif } Debug.Assert(iPos == cbOut); } @@ -152,7 +140,7 @@ namespace ModernKeePassLib.Cryptography } #if !ModernKeePassLib - private static bool? g_obAesCsp = null; + private static bool? g_obAesCsp = null; internal static SymmetricAlgorithm CreateAes() { if(g_obAesCsp.HasValue) @@ -187,5 +175,5 @@ namespace ModernKeePassLib.Cryptography return null; } #endif - } + } } diff --git a/ModernKeePassLib/Cryptography/Hash/HMACSHA256.cs b/ModernKeePassLib/Cryptography/Hash/HMACSHA256.cs new file mode 100644 index 0000000..cfc3ff5 --- /dev/null +++ b/ModernKeePassLib/Cryptography/Hash/HMACSHA256.cs @@ -0,0 +1,35 @@ +using System; +using Org.BouncyCastle.Crypto.Digests; +using Org.BouncyCastle.Crypto.Macs; +using Org.BouncyCastle.Crypto.Parameters; + +namespace ModernKeePassLib.Cryptography.Hash +{ + public class HMACSHA256: IDisposable + + { + private readonly HMac _hmac; + + public HMACSHA256(byte[] key) + { + _hmac = new HMac(new Sha256Digest()); + _hmac.Init(new KeyParameter(key)); + } + + public byte[] ComputeHash(byte[] value) + { + if (value == null) throw new ArgumentNullException("value"); + + byte[] resBuf = new byte[_hmac.GetMacSize()]; + _hmac.BlockUpdate(value, 0, value.Length); + _hmac.DoFinal(resBuf, 0); + + return resBuf; + } + + public void Dispose() + { + _hmac.Reset(); + } + } +} diff --git a/ModernKeePassLib/Cryptography/SelfTest.cs b/ModernKeePassLib/Cryptography/SelfTest.cs index f5796a8..c0a7b3c 100644 --- a/ModernKeePassLib/Cryptography/SelfTest.cs +++ b/ModernKeePassLib/Cryptography/SelfTest.cs @@ -687,8 +687,8 @@ namespace ModernKeePassLib.Cryptography private static void HmacEval(byte[] pbKey, byte[] pbMsg, byte[] pbExpc, string strID) { - // WinRT #if ModernKeePassLib + // WinRT var h = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256).CreateHash(CryptographicBuffer.CreateFromByteArray(pbKey)); h.Append(CryptographicBuffer.CreateFromByteArray(pbMsg)); var pbHash = h.GetValueAndReset().ToArray(); diff --git a/ModernKeePassLib/Keys/KcpPassword.cs b/ModernKeePassLib/Keys/KcpPassword.cs index 9ac094d..19fb048 100644 --- a/ModernKeePassLib/Keys/KcpPassword.cs +++ b/ModernKeePassLib/Keys/KcpPassword.cs @@ -95,12 +95,12 @@ namespace ModernKeePassLib.Keys { try { - string str = StrUtil.Utf8.GetString(pb, 0, pb.Length); #if ModernKeePassLib // TODO: find a way to implement this return true; #else - return str.IsNormalized(NormalizationForm.FormC); + string str = StrUtil.Utf8.GetString(pb); + return str.IsNormalized(NormalizationForm.FormC); #endif } catch(Exception) { Debug.Assert(false); } @@ -108,5 +108,5 @@ namespace ModernKeePassLib.Keys return false; } #endif - } + } } diff --git a/ModernKeePassLib/ModernKeePassLib.csproj b/ModernKeePassLib/ModernKeePassLib.csproj index 2a6fb69..4137d30 100644 --- a/ModernKeePassLib/ModernKeePassLib.csproj +++ b/ModernKeePassLib/ModernKeePassLib.csproj @@ -61,6 +61,7 @@ + diff --git a/ModernKeePassLib/Serialization/KdbxFile.cs b/ModernKeePassLib/Serialization/KdbxFile.cs index ca20d8e..c528c99 100644 --- a/ModernKeePassLib/Serialization/KdbxFile.cs +++ b/ModernKeePassLib/Serialization/KdbxFile.cs @@ -32,13 +32,13 @@ using System.IO.Compression; #endif #if ModernKeePassLib -//using PCLStorage; using Windows.Storage; #endif using ModernKeePassLib.Collections; using ModernKeePassLib.Cryptography; using ModernKeePassLib.Cryptography.Cipher; +using ModernKeePassLib.Cryptography.Hash; using ModernKeePassLib.Cryptography.KeyDerivation; using ModernKeePassLib.Delegates; using ModernKeePassLib.Interfaces; @@ -459,15 +459,10 @@ namespace ModernKeePassLib.Serialization byte[] pbHeaderHmac; byte[] pbBlockKey = HmacBlockStream.GetHmacKey64( pbKey, ulong.MaxValue); -#if ModernKeePassLib - var h = MacAlgorithmProvider.OpenAlgorithm(MacAlgorithmNames.HmacSha256).CreateHash(CryptographicBuffer.CreateFromByteArray(pbHeader)); - CryptographicBuffer.CopyToByteArray(h.GetValueAndReset(), out pbHeaderHmac); -#else using (HMACSHA256 h = new HMACSHA256(pbBlockKey)) { pbHeaderHmac = h.ComputeHash(pbHeader); } -#endif MemUtil.ZeroByteArray(pbBlockKey); return pbHeaderHmac;