Пример #1
0
        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));
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        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
        }