public void TestMemUtil2() { var i = 0 - 0x10203040; var pbRes = MemUtil.Int32ToBytes(i); Assert.That(MemUtil.ByteArrayToHexString(pbRes), Is.EqualTo("C0CFDFEF")); Assert.That(MemUtil.BytesToUInt32(pbRes), Is.EqualTo((uint)i)); Assert.That(MemUtil.BytesToInt32(pbRes), Is.EqualTo(i)); }
private static bool CreateMutexUnix(string strName, bool bInitiallyOwned) { string strPath = GetMutexPath(strName); try { if (File.Exists(strPath)) { byte[] pbEnc = File.ReadAllBytes(strPath); byte[] pb = CryptoUtil.UnprotectData(pbEnc, GmpOptEnt, DataProtectionScope.CurrentUser); if (pb.Length == 12) { long lTime = MemUtil.BytesToInt64(pb, 0); DateTime dt = DateTime.FromBinary(lTime); if ((DateTime.UtcNow - dt).TotalSeconds < GmpMutexValidSecs) { int pid = MemUtil.BytesToInt32(pb, 8); try { Process.GetProcessById(pid); // Throws if process is not running return(false); // Actively owned by other process } catch (Exception) { } } // Release the old mutex since process is not running ReleaseMutexUnix(strName); } else { Debug.Assert(false); } } } catch (Exception) { Debug.Assert(false); } try { WriteMutexFilePriv(strPath); } catch (Exception) { Debug.Assert(false); } m_vMutexesUnix.Add(new KeyValuePair <string, string>(strName, strPath)); return(true); }
private bool ReadInnerHeaderField(BinaryReaderEx br) { Debug.Assert(br != null); if (br == null) { throw new ArgumentNullException("br"); } byte btFieldID = br.ReadByte(); int cbSize = MemUtil.BytesToInt32(br.ReadBytes(4)); if (cbSize < 0) { throw new FormatException(KLRes.FileCorrupted); } byte[] pbData = MemUtil.EmptyByteArray; if (cbSize > 0) { pbData = br.ReadBytes(cbSize); } bool bResult = true; KdbxInnerHeaderFieldID kdbID = (KdbxInnerHeaderFieldID)btFieldID; switch (kdbID) { case KdbxInnerHeaderFieldID.EndOfHeader: bResult = false; // Returning false indicates end of header break; case KdbxInnerHeaderFieldID.InnerRandomStreamID: SetInnerRandomStreamID(pbData); break; case KdbxInnerHeaderFieldID.InnerRandomStreamKey: Debug.Assert(m_pbInnerRandomStreamKey == null); m_pbInnerRandomStreamKey = pbData; CryptoRandom.Instance.AddEntropy(pbData); break; case KdbxInnerHeaderFieldID.Binary: if (pbData.Length < 1) { throw new FormatException(); } KdbxBinaryFlags f = (KdbxBinaryFlags)pbData[0]; bool bProt = ((f & KdbxBinaryFlags.Protected) != KdbxBinaryFlags.None); ProtectedBinary pb = new ProtectedBinary(bProt, pbData, 1, pbData.Length - 1); Debug.Assert(m_pbsBinaries.Find(pb) < 0); // No deduplication? m_pbsBinaries.Add(pb); if (bProt) { MemUtil.ZeroByteArray(pbData); } break; default: Debug.Assert(false); break; } return(bResult); }
private bool ReadHeaderField(BinaryReaderEx brSource) { Debug.Assert(brSource != null); if (brSource == null) { throw new ArgumentNullException("brSource"); } byte btFieldID = brSource.ReadByte(); int cbSize; Debug.Assert(m_uFileVersion > 0); if (m_uFileVersion < FileVersion32_4) { cbSize = (int)MemUtil.BytesToUInt16(brSource.ReadBytes(2)); } else { cbSize = MemUtil.BytesToInt32(brSource.ReadBytes(4)); } if (cbSize < 0) { throw new FormatException(KLRes.FileCorrupted); } byte[] pbData = MemUtil.EmptyByteArray; if (cbSize > 0) { pbData = brSource.ReadBytes(cbSize); } bool bResult = true; KdbxHeaderFieldID kdbID = (KdbxHeaderFieldID)btFieldID; switch (kdbID) { case KdbxHeaderFieldID.EndOfHeader: bResult = false; // Returning false indicates end of header break; case KdbxHeaderFieldID.CipherID: SetCipher(pbData); break; case KdbxHeaderFieldID.CompressionFlags: SetCompressionFlags(pbData); break; case KdbxHeaderFieldID.MasterSeed: m_pbMasterSeed = pbData; CryptoRandom.Instance.AddEntropy(pbData); break; // Obsolete; for backward compatibility only case KdbxHeaderFieldID.TransformSeed: Debug.Assert(m_uFileVersion < FileVersion32_4); AesKdf kdfS = new AesKdf(); if (!m_pwDatabase.KdfParameters.KdfUuid.Equals(kdfS.Uuid)) { m_pwDatabase.KdfParameters = kdfS.GetDefaultParameters(); } // m_pbTransformSeed = pbData; m_pwDatabase.KdfParameters.SetByteArray(AesKdf.ParamSeed, pbData); CryptoRandom.Instance.AddEntropy(pbData); break; // Obsolete; for backward compatibility only case KdbxHeaderFieldID.TransformRounds: Debug.Assert(m_uFileVersion < FileVersion32_4); AesKdf kdfR = new AesKdf(); if (!m_pwDatabase.KdfParameters.KdfUuid.Equals(kdfR.Uuid)) { m_pwDatabase.KdfParameters = kdfR.GetDefaultParameters(); } // m_pwDatabase.KeyEncryptionRounds = MemUtil.BytesToUInt64(pbData); m_pwDatabase.KdfParameters.SetUInt64(AesKdf.ParamRounds, MemUtil.BytesToUInt64(pbData)); break; case KdbxHeaderFieldID.EncryptionIV: m_pbEncryptionIV = pbData; break; case KdbxHeaderFieldID.InnerRandomStreamKey: Debug.Assert(m_uFileVersion < FileVersion32_4); Debug.Assert(m_pbInnerRandomStreamKey == null); m_pbInnerRandomStreamKey = pbData; CryptoRandom.Instance.AddEntropy(pbData); break; case KdbxHeaderFieldID.StreamStartBytes: Debug.Assert(m_uFileVersion < FileVersion32_4); m_pbStreamStartBytes = pbData; break; case KdbxHeaderFieldID.InnerRandomStreamID: Debug.Assert(m_uFileVersion < FileVersion32_4); SetInnerRandomStreamID(pbData); break; case KdbxHeaderFieldID.KdfParameters: m_pwDatabase.KdfParameters = KdfParameters.DeserializeExt(pbData); break; case KdbxHeaderFieldID.PublicCustomData: Debug.Assert(m_pwDatabase.PublicCustomData.Count == 0); m_pwDatabase.PublicCustomData = VariantDictionary.Deserialize(pbData); break; default: Debug.Assert(false); if (m_slLogger != null) { m_slLogger.SetText(KLRes.UnknownHeaderId + ": " + kdbID.ToString() + "!", LogStatusType.Warning); } break; } return(bResult); }
public static VariantDictionary Deserialize(byte[] pb) { if (pb == null) { Debug.Assert(false); return(null); } VariantDictionary d = new VariantDictionary(); using (MemoryStream ms = new MemoryStream(pb, false)) { ushort uVersion = MemUtil.BytesToUInt16(MemUtil.Read(ms, 2)); if ((uVersion & VdmCritical) > (VdVersion & VdmCritical)) { throw new FormatException(KLRes.FileNewVerReq); } while (true) { int iType = ms.ReadByte(); if (iType < 0) { throw new EndOfStreamException(KLRes.FileCorrupted); } byte btType = (byte)iType; if (btType == (byte)VdType.None) { break; } int cbName = MemUtil.BytesToInt32(MemUtil.Read(ms, 4)); byte[] pbName = MemUtil.Read(ms, cbName); if (pbName.Length != cbName) { throw new EndOfStreamException(KLRes.FileCorrupted); } string strName = StrUtil.Utf8.GetString(pbName, 0, pbName.Length); int cbValue = MemUtil.BytesToInt32(MemUtil.Read(ms, 4)); byte[] pbValue = MemUtil.Read(ms, cbValue); if (pbValue.Length != cbValue) { throw new EndOfStreamException(KLRes.FileCorrupted); } switch (btType) { case (byte)VdType.UInt32: if (cbValue == 4) { d.SetUInt32(strName, MemUtil.BytesToUInt32(pbValue)); } else { Debug.Assert(false); } break; case (byte)VdType.UInt64: if (cbValue == 8) { d.SetUInt64(strName, MemUtil.BytesToUInt64(pbValue)); } else { Debug.Assert(false); } break; case (byte)VdType.Bool: if (cbValue == 1) { d.SetBool(strName, (pbValue[0] != 0)); } else { Debug.Assert(false); } break; case (byte)VdType.Int32: if (cbValue == 4) { d.SetInt32(strName, MemUtil.BytesToInt32(pbValue)); } else { Debug.Assert(false); } break; case (byte)VdType.Int64: if (cbValue == 8) { d.SetInt64(strName, MemUtil.BytesToInt64(pbValue)); } else { Debug.Assert(false); } break; case (byte)VdType.String: d.SetString(strName, StrUtil.Utf8.GetString(pbValue, 0, pbValue.Length)); break; case (byte)VdType.ByteArray: d.SetByteArray(strName, pbValue); break; default: Debug.Assert(false); // Unknown type break; } } Debug.Assert(ms.ReadByte() < 0); } return(d); }
private static void TcpProcessMessage(BinaryReader br) { if (br.ReadByte() != 1) { Debug.Assert(false); return; } int cb = MemUtil.BytesToInt32(br.ReadBytes(4)); if ((cb <= 0) || (cb > IpcTcpMsgSizeMax)) { Debug.Assert(false); return; } byte[] pbEnc = br.ReadBytes(cb); if ((pbEnc == null) || (pbEnc.Length != cb)) { Debug.Assert(false); return; } const int cbID = (int)PwUuid.UuidSize; byte[] pb = CryptoUtil.UnprotectData(pbEnc, IpcTcpOptEnt, DataProtectionScope.CurrentUser); if ((pb == null) || (pb.Length != (cbID + 8 + 4 + 4))) { Debug.Assert(false); return; } PwUuid puID = new PwUuid(MemUtil.Mid(pb, 0, cbID)); foreach (KeyValuePair <PwUuid, DateTime> kvp in g_lOldMsgs) { if (puID.Equals(kvp.Key)) { Debug.Assert(false); return; } } DateTime dtNow = DateTime.UtcNow, dtMsg = DateTime.FromBinary( MemUtil.BytesToInt64(pb, cbID)); if ((dtNow - dtMsg).TotalMilliseconds > IpcTcpTtlMs) { Debug.Assert(false); return; } g_lOldMsgs.Add(new KeyValuePair <PwUuid, DateTime>(puID, dtMsg)); int iMsg = MemUtil.BytesToInt32(pb, cbID + 8); int lParam = MemUtil.BytesToInt32(pb, cbID + 8 + 4); MainForm mf = Program.MainForm; VoidDelegate f = delegate() { try { mf.ProcessAppMessage(new IntPtr(iMsg), new IntPtr(lParam)); } catch (Exception) { Debug.Assert(false); } }; mf.Invoke(f); }
private bool ReadSafeBlock() { if (m_bEos) { return(false); // End of stream reached already } byte[] pbStoredHmac = MemUtil.Read(m_sBase, 32); if ((pbStoredHmac == null) || (pbStoredHmac.Length != 32)) { throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncomplete); } // Block index is implicit: it's used in the HMAC computation, // but does not need to be stored // byte[] pbBlockIndex = MemUtil.Read(m_sBase, 8); // if((pbBlockIndex == null) || (pbBlockIndex.Length != 8)) // throw new EndOfStreamException(); // ulong uBlockIndex = MemUtil.BytesToUInt64(pbBlockIndex); // if((uBlockIndex != m_uBlockIndex) && m_bVerify) // throw new InvalidDataException(); byte[] pbBlockIndex = MemUtil.UInt64ToBytes(m_uBlockIndex); byte[] pbBlockSize = MemUtil.Read(m_sBase, 4); if ((pbBlockSize == null) || (pbBlockSize.Length != 4)) { throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncomplete); } int nBlockSize = MemUtil.BytesToInt32(pbBlockSize); if (nBlockSize < 0) { throw new InvalidDataException(KLRes.FileCorrupted); } m_iBufferPos = 0; SetBuffer(MemUtil.Read(m_sBase, nBlockSize)); if ((m_pbBuffer == null) || ((m_pbBuffer.Length != nBlockSize) && m_bVerify)) { throw new EndOfStreamException(KLRes.FileCorrupted + " " + KLRes.FileIncompleteExpc); } if (m_bVerify) { byte[] pbCmpHmac; byte[] pbBlockKey = GetHmacKey64(m_pbKey, m_uBlockIndex); using (HMACSHA256 h = new HMACSHA256(pbBlockKey)) { h.TransformBlock(pbBlockIndex, 0, pbBlockIndex.Length, pbBlockIndex, 0); h.TransformBlock(pbBlockSize, 0, pbBlockSize.Length, pbBlockSize, 0); if (m_pbBuffer.Length != 0) { h.TransformBlock(m_pbBuffer, 0, m_pbBuffer.Length, m_pbBuffer, 0); } h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0); pbCmpHmac = h.Hash; } MemUtil.ZeroByteArray(pbBlockKey); if (!MemUtil.ArraysEqual(pbCmpHmac, pbStoredHmac)) { throw new InvalidDataException(KLRes.FileCorrupted); } } ++m_uBlockIndex; if (nBlockSize == 0) { m_bEos = true; return(false); // No further data available } return(true); }
private static void TestMemUtil() { #if DEBUG Random r = new Random(); byte[] pb = CryptoRandom.Instance.GetRandomBytes((uint)r.Next( 0, 0x2FFFF)); byte[] pbCompressed = MemUtil.Compress(pb); if (!MemUtil.ArraysEqual(MemUtil.Decompress(pbCompressed), pb)) { throw new InvalidOperationException("GZip"); } Encoding enc = StrUtil.Utf8; pb = enc.GetBytes("012345678901234567890a"); byte[] pbN = enc.GetBytes("9012"); if (MemUtil.IndexOf <byte>(pb, pbN) != 9) { throw new InvalidOperationException("MemUtil-1"); } pbN = enc.GetBytes("01234567890123"); if (MemUtil.IndexOf <byte>(pb, pbN) != 0) { throw new InvalidOperationException("MemUtil-2"); } pbN = enc.GetBytes("a"); if (MemUtil.IndexOf <byte>(pb, pbN) != 21) { throw new InvalidOperationException("MemUtil-3"); } pbN = enc.GetBytes("0a"); if (MemUtil.IndexOf <byte>(pb, pbN) != 20) { throw new InvalidOperationException("MemUtil-4"); } pbN = enc.GetBytes("1"); if (MemUtil.IndexOf <byte>(pb, pbN) != 1) { throw new InvalidOperationException("MemUtil-5"); } pbN = enc.GetBytes("b"); if (MemUtil.IndexOf <byte>(pb, pbN) >= 0) { throw new InvalidOperationException("MemUtil-6"); } pbN = enc.GetBytes("012b"); if (MemUtil.IndexOf <byte>(pb, pbN) >= 0) { throw new InvalidOperationException("MemUtil-7"); } byte[] pbRes = MemUtil.ParseBase32("MY======"); byte[] pbExp = Encoding.ASCII.GetBytes("f"); if (!MemUtil.ArraysEqual(pbRes, pbExp)) { throw new Exception("Base32-1"); } pbRes = MemUtil.ParseBase32("MZXQ===="); pbExp = Encoding.ASCII.GetBytes("fo"); if (!MemUtil.ArraysEqual(pbRes, pbExp)) { throw new Exception("Base32-2"); } pbRes = MemUtil.ParseBase32("MZXW6==="); pbExp = Encoding.ASCII.GetBytes("foo"); if (!MemUtil.ArraysEqual(pbRes, pbExp)) { throw new Exception("Base32-3"); } pbRes = MemUtil.ParseBase32("MZXW6YQ="); pbExp = Encoding.ASCII.GetBytes("foob"); if (!MemUtil.ArraysEqual(pbRes, pbExp)) { throw new Exception("Base32-4"); } pbRes = MemUtil.ParseBase32("MZXW6YTB"); pbExp = Encoding.ASCII.GetBytes("fooba"); if (!MemUtil.ArraysEqual(pbRes, pbExp)) { throw new Exception("Base32-5"); } pbRes = MemUtil.ParseBase32("MZXW6YTBOI======"); pbExp = Encoding.ASCII.GetBytes("foobar"); if (!MemUtil.ArraysEqual(pbRes, pbExp)) { throw new Exception("Base32-6"); } pbRes = MemUtil.ParseBase32("JNSXSIDQOJXXM2LEMVZCAYTBONSWIIDPNYQG63TFFV2GS3LFEBYGC43TO5XXEZDTFY======"); pbExp = Encoding.ASCII.GetBytes("Key provider based on one-time passwords."); if (!MemUtil.ArraysEqual(pbRes, pbExp)) { throw new Exception("Base32-7"); } int i = 0 - 0x10203040; pbRes = MemUtil.Int32ToBytes(i); if (MemUtil.ByteArrayToHexString(pbRes) != "C0CFDFEF") { throw new Exception("MemUtil-8"); // Must be little-endian } if (MemUtil.BytesToUInt32(pbRes) != (uint)i) { throw new Exception("MemUtil-9"); } if (MemUtil.BytesToInt32(pbRes) != i) { throw new Exception("MemUtil-10"); } #endif }