예제 #1
0
        public KcpCustomKey(byte[] pbKeyData)
        {
            Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");

            SHA256Managed sha256 = new SHA256Managed();
            byte[] pbRaw = sha256.ComputeHash(pbKeyData);
            m_pbKey = new ProtectedBinary(true, pbRaw);
        }
		/// <summary>
		/// Clear the key and securely erase all security-critical information.
		/// </summary>
		public void Clear()
		{
			if(m_pbKeyData != null)
			{
				m_pbKeyData.Clear();
				m_pbKeyData = null;
			}
		}
예제 #3
0
		/// <summary>
		/// Clear the key and securely erase all security-critical information.
		/// </summary>
		public void Clear()
		{
			m_strPath = string.Empty;

			if(m_pbKeyData != null)
			{
				m_pbKeyData.Clear();
				m_pbKeyData = null;
			}
		}
예제 #4
0
		public KcpKeyFile(string strKeyFile)
		{
			byte[] pbKey = LoadXmlKeyFile(strKeyFile);
			if(pbKey == null) pbKey = LoadKeyFile(strKeyFile);

			if(pbKey == null) throw new InvalidOperationException();

			m_strPath = strKeyFile;
			m_pbKeyData = new ProtectedBinary(true, pbKey);
		}
예제 #5
0
		private void SetKey(byte[] pbPasswordUtf8)
		{
			Debug.Assert(pbPasswordUtf8 != null);
			if(pbPasswordUtf8 == null) throw new ArgumentNullException("pbPasswordUtf8");

			SHA256Managed sha256 = new SHA256Managed();
			byte[] pbRaw = sha256.ComputeHash(pbPasswordUtf8);

			m_psPassword = new ProtectedString(true, pbPasswordUtf8);
			m_pbKeyData = new ProtectedBinary(true, pbRaw);
		}
예제 #6
0
		internal static ProtectedString GetKeyParts(byte[] pbPasswordUtf8, out ProtectedBinary pbKeyData)
		{
			Debug.Assert(pbPasswordUtf8 != null);
			if(pbPasswordUtf8 == null) throw new ArgumentNullException("pbPasswordUtf8");

			SHA256Managed sha256 = new SHA256Managed();
			byte[] pbRaw = sha256.ComputeHash(pbPasswordUtf8);

			var psPassword = new ProtectedString(true, pbPasswordUtf8);
			pbKeyData = new ProtectedBinary(true, pbRaw);
			return psPassword;
		}
예제 #7
0
		private void SetKey(byte[] pbPasswordUtf8)
		{
			Debug.Assert(pbPasswordUtf8 != null);
			if(pbPasswordUtf8 == null) throw new ArgumentNullException("pbPasswordUtf8");

#if (DEBUG && !KeePassLibSD)
			Debug.Assert(ValidatePassword(pbPasswordUtf8));
#endif

			byte[] pbRaw = CryptoUtil.HashSha256(pbPasswordUtf8);

			m_psPassword = new ProtectedString(true, pbPasswordUtf8);
			m_pbKeyData = new ProtectedBinary(true, pbRaw);
		}
예제 #8
0
        public KcpCustomKey(string strName, byte[] pbKeyData, bool bPerformHash)
        {
            Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
            Debug.Assert(pbKeyData != null); if(pbKeyData == null) throw new ArgumentNullException("pbKeyData");

            m_strName = strName;

            if(bPerformHash)
            {
                SHA256Managed sha256 = new SHA256Managed();
                byte[] pbRaw = sha256.ComputeHash(pbKeyData);
                m_pbKey = new ProtectedBinary(true, pbRaw);
            }
            else m_pbKey = new ProtectedBinary(true, pbKeyData);
        }
		/// <summary>
		/// Construct a user account key.
		/// </summary>
		public KcpUserAccount()
		{
			// Test if ProtectedData is supported -- throws an exception
			// when running on an old system (Windows 98 / ME).
			byte[] pbDummyData = new byte[128];
			ProtectedData.Protect(pbDummyData, m_pbEntropy,
				DataProtectionScope.CurrentUser);

			byte[] pbKey = LoadUserKey(false);
			if(pbKey == null) pbKey = CreateUserKey();
			if(pbKey == null) throw new SecurityException(KLRes.UserAccountKeyError);

			m_pbKeyData = new ProtectedBinary(true, pbKey);
			Array.Clear(pbKey, 0, pbKey.Length);
		}
예제 #10
0
        /// <summary>
        /// Construct a user account key.
        /// </summary>
        public KcpUserAccount()
        {
            // Test if ProtectedData is supported -- throws an exception
            // when running on an old system (Windows 98 / ME).
            byte[] pbDummyData = new byte[128];
            ProtectedData.Protect(pbDummyData, m_pbEntropy,
                DataProtectionScope.CurrentUser);

            byte[] pbKey = LoadUserKey(false);
            if(pbKey == null) pbKey = CreateUserKey();
            if(pbKey == null) // Should never happen
            {
                Debug.Assert(false);
                throw new SecurityException(KLRes.UserAccountKeyError);
            }

            m_pbKeyData = new ProtectedBinary(true, pbKey);
            MemUtil.ZeroByteArray(pbKey);
        }
예제 #11
0
		private void Init(bool bEnableProtection, byte[] pbUtf8)
		{
			if(pbUtf8 == null) throw new ArgumentNullException("pbUtf8");

			m_bIsProtected = bEnableProtection;

			if(bEnableProtection)
				m_pbUtf8 = new ProtectedBinary(true, pbUtf8);
			else
				m_strPlainText = StrUtil.Utf8.GetString(pbUtf8, 0, pbUtf8.Length);
		}
예제 #12
0
        public static void UpdateKeePassEntry(PwEntry entry,
            string username = "",
            string title = "",
            string url = "",
            string notes = "",
            string password = "",
            string[] attachments = null,
            string[] tags = null)
        {
            UpdateValue(entry, "UserName", username);
            UpdateValue(entry, "Title", title);
            UpdateValue(entry, "URL", url);
            UpdateValue(entry, "Notes", notes);
            UpdateValue(entry, "Password", password);

            if(tags != null)
            {
                var tagsCopy = entry.Tags.ToArray();
                foreach(var tag in tagsCopy)
                    entry.RemoveTag(tag);

                foreach (var tag in tags)
                    entry.AddTag(tag);
            }

            if (attachments != null)
            {
                var fileNames = attachments.Select(o => Path.GetFileName(o)).ToList();
                var binaries = entry.Binaries.CloneDeep();
                var filesToAdd = new List<string>();

                foreach(var binary in binaries)
                {
                    entry.Binaries.Remove(binary.Key);
                }

                foreach(var attachment in attachments)
                {
                    var fileName = Path.GetFileName(attachment);

                    var bytes = File.ReadAllBytes(attachment);
                    if(bytes != null)
                    {
                        var protectedBytes = new ProtectedBinary(true, bytes);
                        entry.Binaries.Set(fileName, protectedBytes);
                    }
                }
            }
        }
예제 #13
0
        private void Construct(IOConnectionInfo iocFile)
        {
            byte[] pbKey = LoadXmlKeyFile(iocFile);
            if(pbKey == null) pbKey = LoadKeyFile(iocFile);

            if(pbKey == null) throw new InvalidOperationException();

            m_strPath = iocFile.Path;
            m_pbKeyData = new ProtectedBinary(true, pbKey);
        }
		private KdbContext EndXmlElement(KdbContext ctx, XmlReader xr)
		{
			Debug.Assert(xr.NodeType == XmlNodeType.EndElement);

			if((ctx == KdbContext.KeePassFile) && (xr.Name == ElemDocNode))
				return KdbContext.Null;
			else if((ctx == KdbContext.Meta) && (xr.Name == ElemMeta))
				return KdbContext.KeePassFile;
			else if((ctx == KdbContext.Root) && (xr.Name == ElemRoot))
				return KdbContext.KeePassFile;
			else if((ctx == KdbContext.MemoryProtection) && (xr.Name == ElemMemoryProt))
				return KdbContext.Meta;
			else if((ctx == KdbContext.CustomIcons) && (xr.Name == ElemCustomIcons))
				return KdbContext.Meta;
			else if((ctx == KdbContext.CustomIcon) && (xr.Name == ElemCustomIconItem))
			{
				if(!m_uuidCustomIconID.Equals(PwUuid.Zero) &&
					(m_pbCustomIconData != null))
					m_pwDatabase.CustomIcons.Add(new PwCustomIcon(
						m_uuidCustomIconID, m_pbCustomIconData));
				else { Debug.Assert(false); }

				m_uuidCustomIconID = PwUuid.Zero;
				m_pbCustomIconData = null;

				return KdbContext.CustomIcons;
			}
			else if((ctx == KdbContext.Binaries) && (xr.Name == ElemBinaries))
				return KdbContext.Meta;
			else if((ctx == KdbContext.CustomData) && (xr.Name == ElemCustomData))
				return KdbContext.Meta;
			else if((ctx == KdbContext.CustomDataItem) && (xr.Name == ElemStringDictExItem))
			{
				if((m_strCustomDataKey != null) && (m_strCustomDataValue != null))
					m_pwDatabase.CustomData.Set(m_strCustomDataKey, m_strCustomDataValue);
				else { Debug.Assert(false); }

				m_strCustomDataKey = null;
				m_strCustomDataValue = null;

				return KdbContext.CustomData;
			}
			else if((ctx == KdbContext.Group) && (xr.Name == ElemGroup))
			{
				if(PwUuid.Zero.Equals(m_ctxGroup.Uuid))
					m_ctxGroup.Uuid = new PwUuid(true); // No assert (import)

				m_ctxGroups.Pop();

				if(m_ctxGroups.Count == 0)
				{
					m_ctxGroup = null;
					return KdbContext.Root;
				}
				else
				{
					m_ctxGroup = m_ctxGroups.Peek();
					return KdbContext.Group;
				}
			}
			else if((ctx == KdbContext.GroupTimes) && (xr.Name == ElemTimes))
				return KdbContext.Group;
			else if((ctx == KdbContext.Entry) && (xr.Name == ElemEntry))
			{
				// Create new UUID if absent
				if(PwUuid.Zero.Equals(m_ctxEntry.Uuid))
					m_ctxEntry.Uuid = new PwUuid(true); // No assert (import)

				if(m_bEntryInHistory)
				{
					m_ctxEntry = m_ctxHistoryBase;
					return KdbContext.EntryHistory;
				}

				return KdbContext.Group;
			}
			else if((ctx == KdbContext.EntryTimes) && (xr.Name == ElemTimes))
				return KdbContext.Entry;
			else if((ctx == KdbContext.EntryString) && (xr.Name == ElemString))
			{
				m_ctxEntry.Strings.Set(m_ctxStringName, m_ctxStringValue);
				m_ctxStringName = null;
				m_ctxStringValue = null;
				return KdbContext.Entry;
			}
			else if((ctx == KdbContext.EntryBinary) && (xr.Name == ElemBinary))
			{
				if(string.IsNullOrEmpty(m_strDetachBins))
					m_ctxEntry.Binaries.Set(m_ctxBinaryName, m_ctxBinaryValue);
				else
				{
					SaveBinary(m_ctxBinaryName, m_ctxBinaryValue, m_strDetachBins);

					m_ctxBinaryValue = null;
					GC.Collect();
				}

				m_ctxBinaryName = null;
				m_ctxBinaryValue = null;
				return KdbContext.Entry;
			}
			else if((ctx == KdbContext.EntryAutoType) && (xr.Name == ElemAutoType))
				return KdbContext.Entry;
			else if((ctx == KdbContext.EntryAutoTypeItem) && (xr.Name == ElemAutoTypeItem))
			{
				AutoTypeAssociation atAssoc = new AutoTypeAssociation(m_ctxATName,
					m_ctxATSeq);
				m_ctxEntry.AutoType.Add(atAssoc);
				m_ctxATName = null;
				m_ctxATSeq = null;
				return KdbContext.EntryAutoType;
			}
			else if((ctx == KdbContext.EntryHistory) && (xr.Name == ElemHistory))
			{
				m_bEntryInHistory = false;
				return KdbContext.Entry;
			}
			else if((ctx == KdbContext.RootDeletedObjects) && (xr.Name == ElemDeletedObjects))
				return KdbContext.Root;
			else if((ctx == KdbContext.DeletedObject) && (xr.Name == ElemDeletedObject))
			{
				m_ctxDeletedObject = null;
				return KdbContext.RootDeletedObjects;
			}
			else
			{
				Debug.Assert(false);
				throw new FormatException();
			}
		}
예제 #15
0
        private void OnCtxBinNew(object sender, EventArgs e)
        {
            if(m_pwEditMode == PwEditMode.ViewReadOnlyEntry) return;

            string strName;
            for(int i = 0; ; ++i)
            {
                strName = KPRes.New;
                if(i >= 1) strName += " (" + i.ToString() + ")";
                strName += ".rtf";

                if(m_vBinaries.Get(strName) == null) break;
            }

            ProtectedBinary pb = new ProtectedBinary();
            m_vBinaries.Set(strName, pb);
            UpdateEntryBinaries(false, true, strName);
            ResizeColumnHeaders();

            ListViewItem lviNew = m_lvBinaries.FindItemWithText(strName,
                false, 0, false);
            if(lviNew != null) lviNew.BeginEdit();
        }
예제 #16
0
파일: KdbxFile.cs 프로젝트: saadware/kpn
        private string BinPoolFind(ProtectedBinary pb)
        {
            if(pb == null) { Debug.Assert(false); return null; }

            foreach(KeyValuePair<string, ProtectedBinary> kvp in m_dictBinPool)
            {
                if(pb.Equals(kvp.Value)) return kvp.Key;
            }

            return null;
        }
		/// <summary>
		/// Construct a new protected binary data object. Copy the data from
		/// an existing object.
		/// </summary>
		/// <param name="pbTemplate">Existing <c>ProtectedBinary</c> object,
		/// which is used to initialize the new object. This parameter must
		/// not be <c>null</c>.</param>
		/// <exception cref="System.ArgumentNullException">Thrown if the input
		/// parameter is <c>null</c>.</exception>
		public ProtectedBinary(ProtectedBinary pbTemplate)
		{
			Debug.Assert(pbTemplate != null); if(pbTemplate == null) throw new ArgumentNullException("pbTemplate");

			m_bDoProtect = pbTemplate.m_bDoProtect;

			byte[] pbBuf = pbTemplate.ReadData();
			SetData(pbBuf);
			MemUtil.ZeroByteArray(pbBuf);
		}
예제 #18
0
파일: KdbxFile.cs 프로젝트: saadware/kpn
        private void BinPoolAdd(ProtectedBinary pb)
        {
            if(pb == null) { Debug.Assert(false); return; }

            if(BinPoolFind(pb) != null) return; // Exists already

            m_dictBinPool.Add(m_dictBinPool.Count.ToString(), pb);
        }
예제 #19
0
파일: KdbxFile.cs 프로젝트: saadware/kpn
        private static void SaveBinary(string strName, ProtectedBinary pb,
			string strSaveDir)
        {
            if(pb == null) { Debug.Assert(false); return; }

            if(string.IsNullOrEmpty(strName)) strName = "File.bin";

            string strPath;
            int iTry = 1;
            do
            {
                strPath = UrlUtil.EnsureTerminatingSeparator(strSaveDir, false);

                string strExt = UrlUtil.GetExtension(strName);
                string strDesc = UrlUtil.StripExtension(strName);

                strPath += strDesc;
                if(iTry > 1) strPath += " (" + iTry.ToString() + ")";

                if(!string.IsNullOrEmpty(strExt)) strPath += "." + strExt;

                ++iTry;
            }
            while(File.Exists(strPath));

            #if !KeePassLibSD
            byte[] pbData = pb.ReadData();
            File.WriteAllBytes(strPath, pbData);
            MemUtil.ZeroByteArray(pbData);
            #else
            FileStream fs = new FileStream(strPath, FileMode.Create,
                FileAccess.Write, FileShare.None);
            byte[] pbData = pb.ReadData();
            fs.Write(pbData, 0, pbData.Length);
            fs.Close();
            #endif
        }
예제 #20
0
        private void Construct(IOConnectionInfo iocFile)
        {
            byte[] pbFileData = IOConnection.ReadFile(iocFile);
            if(pbFileData == null) throw new FileNotFoundException();

            byte[] pbKey = LoadXmlKeyFile(pbFileData);
            if(pbKey == null) pbKey = LoadKeyFile(pbFileData);

            if(pbKey == null) throw new InvalidOperationException();

            m_strPath = iocFile.Path;
            m_pbKeyData = new ProtectedBinary(true, pbKey);

            MemUtil.ZeroByteArray(pbKey);
        }
예제 #21
0
		/// <summary>
		/// Convert the protected string to a normal string object.
		/// Be careful with this function, the returned string object
		/// isn't protected anymore and stored in plain-text in the
		/// process memory.
		/// </summary>
		/// <returns>Plain-text string. Is never <c>null</c>.</returns>
		public string ReadString()
		{
			if(m_strPlainText != null) return m_strPlainText;

			byte[] pb = ReadUtf8();
			string str = ((pb.Length == 0) ? string.Empty :
				StrUtil.Utf8.GetString(pb, 0, pb.Length));
			// No need to clear pb

			// As the text is now visible in process memory anyway,
			// there's no need to protect it anymore
			m_strPlainText = str;
			m_pbUtf8 = null; // Thread-safe order

			return str;
		}
예제 #22
0
        public KcpUserAccount(byte[] pbKey)
        {
            //byte[] pbDummyData = new byte[128];
            //ProtectedData.Protect(pbDummyData, m_pbEntropy,
            //    DataProtectionScope.CurrentUser);

            m_pbKeyData = new ProtectedBinary(true, pbKey);
        }
예제 #23
0
        /// <summary>
        /// Generate a 32-bit wide key out of the composite key.
        /// </summary>
        /// <param name="pbKeySeed32">Seed used in the key transformation
        /// rounds. Must be a byte array containing exactly 32 bytes; must
        /// not be null.</param>
        /// <param name="uNumRounds">Number of key transformation rounds.</param>
        /// <returns>Returns a protected binary object that contains the
        /// resulting 32-bit wide key.</returns>
        public ProtectedBinary GenerateKey32(byte[] pbKeySeed32, ulong uNumRounds)
        {
            Debug.Assert(pbKeySeed32 != null);
            if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
            Debug.Assert(pbKeySeed32.Length == 32);
            if(pbKeySeed32.Length != 32) throw new ArgumentException("pbKeySeed32");

            byte[] pbRaw32 = CreateRawCompositeKey32();
            if((pbRaw32 == null) || (pbRaw32.Length != 32))
                { Debug.Assert(false); return null; }

            byte[] pbTrf32 = TransformKey(pbRaw32, pbKeySeed32, uNumRounds);
            if((pbTrf32 == null) || (pbTrf32.Length != 32))
                { Debug.Assert(false); return null; }

            ProtectedBinary pbRet = new ProtectedBinary(true, pbTrf32);
            MemUtil.ZeroByteArray(pbTrf32);
            MemUtil.ZeroByteArray(pbRaw32);

            return pbRet;
        }
예제 #24
0
        private static void ReadEntry(XmlNode xmlNode, PwDatabase pwStorage)
        {
            PwEntry pe = new PwEntry(true, true);
            PwGroup pg = pwStorage.RootGroup;

            string strAttachDesc = null, strAttachment = null;

            foreach(XmlNode xmlChild in xmlNode)
            {
                if(xmlChild.Name == ElemGroup)
                {
                    string strPreTree = null;
                    try
                    {
                        XmlNode xmlTree = xmlChild.Attributes.GetNamedItem(AttribGroupTree);
                        strPreTree = xmlTree.Value;
                    }
                    catch(Exception) { }

                    string strLast = XmlUtil.SafeInnerText(xmlChild);
                    string strGroup = ((!string.IsNullOrEmpty(strPreTree)) ?
                        strPreTree + "\\" + strLast : strLast);

                    pg = pwStorage.RootGroup.FindCreateSubTree(strGroup,
                        new string[1]{ "\\" }, true);
                }
                else if(xmlChild.Name == ElemTitle)
                    pe.Strings.Set(PwDefs.TitleField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectTitle,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemUserName)
                    pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectUserName,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemUrl)
                    pe.Strings.Set(PwDefs.UrlField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectUrl,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemPassword)
                    pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectPassword,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemNotes)
                    pe.Strings.Set(PwDefs.NotesField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectNotes,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemUuid)
                    pe.SetUuid(new PwUuid(MemUtil.HexStringToByteArray(
                        XmlUtil.SafeInnerText(xmlChild))), false);
                else if(xmlChild.Name == ElemImage)
                {
                    int nImage;
                    if(int.TryParse(XmlUtil.SafeInnerText(xmlChild), out nImage))
                    {
                        if((nImage >= 0) && (nImage < (int)PwIcon.Count))
                            pe.IconId = (PwIcon)nImage;
                        else { Debug.Assert(false); }
                    }
                    else { Debug.Assert(false); }
                }
                else if(xmlChild.Name == ElemCreationTime)
                    pe.CreationTime = ParseTime(XmlUtil.SafeInnerText(xmlChild));
                else if(xmlChild.Name == ElemLastModTime)
                    pe.LastModificationTime = ParseTime(XmlUtil.SafeInnerText(xmlChild));
                else if(xmlChild.Name == ElemLastAccessTime)
                    pe.LastAccessTime = ParseTime(XmlUtil.SafeInnerText(xmlChild));
                else if(xmlChild.Name == ElemExpiryTime)
                {
                    try
                    {
                        XmlNode xmlExpires = xmlChild.Attributes.GetNamedItem(AttribExpires);
                        if(StrUtil.StringToBool(xmlExpires.Value))
                        {
                            pe.Expires = true;
                            pe.ExpiryTime = ParseTime(XmlUtil.SafeInnerText(xmlChild));
                        }
                        else { Debug.Assert(ParseTime(XmlUtil.SafeInnerText(xmlChild)).Year == 2999); }
                    }
                    catch(Exception) { Debug.Assert(false); }
                }
                else if(xmlChild.Name == ElemAttachDesc)
                    strAttachDesc = XmlUtil.SafeInnerText(xmlChild);
                else if(xmlChild.Name == ElemAttachment)
                    strAttachment = XmlUtil.SafeInnerText(xmlChild);
                else { Debug.Assert(false); }
            }

            if(!string.IsNullOrEmpty(strAttachDesc) && (strAttachment != null))
            {
                byte[] pbData = Convert.FromBase64String(strAttachment);
                ProtectedBinary pb = new ProtectedBinary(false, pbData);
                pe.Binaries.Set(strAttachDesc, pb);
            }

            pg.AddEntry(pe, true);
        }
예제 #25
0
        private static void ReadEntry(XmlNode xmlNode, PwGroup pgParent,
            PwDatabase pwStorage)
        {
            PwEntry pe = new PwEntry(true, true);
            pgParent.AddEntry(pe, true);

            string strAttachDesc = null, strAttachment = null;

            foreach(XmlNode xmlChild in xmlNode)
            {
                if(xmlChild.Name == ElemTitle)
                    pe.Strings.Set(PwDefs.TitleField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectTitle,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemUserName)
                    pe.Strings.Set(PwDefs.UserNameField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectUserName,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemUrl)
                    pe.Strings.Set(PwDefs.UrlField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectUrl,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemPassword)
                    pe.Strings.Set(PwDefs.PasswordField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectPassword,
                        XmlUtil.SafeInnerText(xmlChild)));
                else if(xmlChild.Name == ElemNotes)
                    pe.Strings.Set(PwDefs.NotesField, new ProtectedString(
                        pwStorage.MemoryProtection.ProtectNotes,
                        FilterSpecial(XmlUtil.SafeInnerXml(xmlChild))));
                else if(xmlChild.Name == ElemIcon)
                    pe.IconId = ReadIcon(xmlChild, pe.IconId);
                else if(xmlChild.Name == ElemCreationTime)
                    pe.CreationTime = ParseTime(XmlUtil.SafeInnerText(xmlChild));
                else if(xmlChild.Name == ElemLastModTime)
                    pe.LastModificationTime = ParseTime(XmlUtil.SafeInnerText(xmlChild));
                else if(xmlChild.Name == ElemLastAccessTime)
                    pe.LastAccessTime = ParseTime(XmlUtil.SafeInnerText(xmlChild));
                else if(xmlChild.Name == ElemExpiryTime)
                {
                    string strDate = XmlUtil.SafeInnerText(xmlChild);
                    pe.Expires = (strDate != ValueNever);
                    if(pe.Expires) pe.ExpiryTime = ParseTime(strDate);
                }
                else if(xmlChild.Name == ElemAttachDesc)
                    strAttachDesc = XmlUtil.SafeInnerText(xmlChild);
                else if(xmlChild.Name == ElemAttachment)
                    strAttachment = XmlUtil.SafeInnerText(xmlChild);
                else { Debug.Assert(false); }
            }

            if(!string.IsNullOrEmpty(strAttachDesc) && (strAttachment != null))
            {
                byte[] pbData = Convert.FromBase64String(strAttachment);
                ProtectedBinary pb = new ProtectedBinary(false, pbData);
                pe.Binaries.Set(strAttachDesc, pb);
            }
        }
예제 #26
0
        /// <summary>
        /// Clear the key and securely erase all security-critical information.
        /// </summary>
        public void Clear()
        {
            if(m_psPassword != null)
            {
                m_psPassword.Clear();
                m_psPassword = null;
            }

            if(m_pbKeyData != null)
            {
                m_pbKeyData.Clear();
                m_pbKeyData = null;
            }
        }
예제 #27
0
        private void BinImportFiles(string[] vPaths)
        {
            if(vPaths == null) { Debug.Assert(false); return; }

            UpdateEntryBinaries(true, false);

            foreach(string strFile in vPaths)
            {
                if(string.IsNullOrEmpty(strFile)) { Debug.Assert(false); continue; }

                byte[] vBytes = null;
                string strMsg, strItem = UrlUtil.GetFileName(strFile);

                if(m_vBinaries.Get(strItem) != null)
                {
                    strMsg = KPRes.AttachedExistsAlready + MessageService.NewLine +
                        strItem + MessageService.NewParagraph + KPRes.AttachNewRename +
                        MessageService.NewParagraph + KPRes.AttachNewRenameRemarks0 +
                        MessageService.NewLine + KPRes.AttachNewRenameRemarks1 +
                        MessageService.NewLine + KPRes.AttachNewRenameRemarks2;

                    DialogResult dr = MessageService.Ask(strMsg, null,
                        MessageBoxButtons.YesNoCancel);

                    if(dr == DialogResult.Cancel) continue;
                    else if(dr == DialogResult.Yes)
                    {
                        string strFileName = UrlUtil.StripExtension(strItem);
                        string strExtension = "." + UrlUtil.GetExtension(strItem);

                        int nTry = 0;
                        while(true)
                        {
                            string strNewName = strFileName + nTry.ToString() + strExtension;
                            if(m_vBinaries.Get(strNewName) == null)
                            {
                                strItem = strNewName;
                                break;
                            }

                            ++nTry;
                        }
                    }
                }

                try
                {
                    vBytes = File.ReadAllBytes(strFile);
                    vBytes = DataEditorForm.ConvertAttachment(strItem, vBytes);

                    if(vBytes != null)
                    {
                        ProtectedBinary pb = new ProtectedBinary(false, vBytes);
                        m_vBinaries.Set(strItem, pb);
                    }
                }
                catch(Exception exAttach)
                {
                    MessageService.ShowWarning(KPRes.AttachFailed, strFile, exAttach);
                }
            }

            UpdateEntryBinaries(false, true);
            ResizeColumnHeaders();
        }
		private KdbContext ReadXmlElement(KdbContext ctx, XmlReader xr)
		{
			Debug.Assert(xr.NodeType == XmlNodeType.Element);

			switch(ctx)
			{
				case KdbContext.Null:
					if(xr.Name == ElemDocNode)
						return SwitchContext(ctx, KdbContext.KeePassFile, xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.KeePassFile:
					if(xr.Name == ElemMeta)
						return SwitchContext(ctx, KdbContext.Meta, xr);
					else if(xr.Name == ElemRoot)
						return SwitchContext(ctx, KdbContext.Root, xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.Meta:
					if(xr.Name == ElemGenerator)
						ReadString(xr); // Ignore
					else if(xr.Name == ElemHeaderHash)
					{
						string strHash = ReadString(xr);
						if(!string.IsNullOrEmpty(strHash) && (m_pbHashOfHeader != null) &&
							!m_bRepairMode)
						{
							byte[] pbHash = Convert.FromBase64String(strHash);
							if(!MemUtil.ArraysEqual(pbHash, m_pbHashOfHeader))
								throw new IOException(KLRes.FileCorrupted);
						}
					}
					else if(xr.Name == ElemDbName)
						m_pwDatabase.Name = ReadString(xr);
					else if(xr.Name == ElemDbNameChanged)
						m_pwDatabase.NameChanged = ReadTime(xr);
					else if(xr.Name == ElemDbDesc)
						m_pwDatabase.Description = ReadString(xr);
					else if(xr.Name == ElemDbDescChanged)
						m_pwDatabase.DescriptionChanged = ReadTime(xr);
					else if(xr.Name == ElemDbDefaultUser)
						m_pwDatabase.DefaultUserName = ReadString(xr);
					else if(xr.Name == ElemDbDefaultUserChanged)
						m_pwDatabase.DefaultUserNameChanged = ReadTime(xr);
					else if(xr.Name == ElemDbMntncHistoryDays)
						m_pwDatabase.MaintenanceHistoryDays = ReadUInt(xr, 365);
					else if(xr.Name == ElemDbColor)
					{
						string strColor = ReadString(xr);
						if(!string.IsNullOrEmpty(strColor))
							m_pwDatabase.Color = ColorTranslator.FromHtml(strColor);
					}
					else if(xr.Name == ElemDbKeyChanged)
						m_pwDatabase.MasterKeyChanged = ReadTime(xr);
					else if(xr.Name == ElemDbKeyChangeRec)
						m_pwDatabase.MasterKeyChangeRec = ReadLong(xr, -1);
					else if(xr.Name == ElemDbKeyChangeForce)
						m_pwDatabase.MasterKeyChangeForce = ReadLong(xr, -1);
					else if(xr.Name == ElemMemoryProt)
						return SwitchContext(ctx, KdbContext.MemoryProtection, xr);
					else if(xr.Name == ElemCustomIcons)
						return SwitchContext(ctx, KdbContext.CustomIcons, xr);
					else if(xr.Name == ElemRecycleBinEnabled)
						m_pwDatabase.RecycleBinEnabled = ReadBool(xr, true);
					else if(xr.Name == ElemRecycleBinUuid)
						m_pwDatabase.RecycleBinUuid = ReadUuid(xr);
					else if(xr.Name == ElemRecycleBinChanged)
						m_pwDatabase.RecycleBinChanged = ReadTime(xr);
					else if(xr.Name == ElemEntryTemplatesGroup)
						m_pwDatabase.EntryTemplatesGroup = ReadUuid(xr);
					else if(xr.Name == ElemEntryTemplatesGroupChanged)
						m_pwDatabase.EntryTemplatesGroupChanged = ReadTime(xr);
					else if(xr.Name == ElemHistoryMaxItems)
						m_pwDatabase.HistoryMaxItems = ReadInt(xr, -1);
					else if(xr.Name == ElemHistoryMaxSize)
						m_pwDatabase.HistoryMaxSize = ReadLong(xr, -1);
					else if(xr.Name == ElemLastSelectedGroup)
						m_pwDatabase.LastSelectedGroup = ReadUuid(xr);
					else if(xr.Name == ElemLastTopVisibleGroup)
						m_pwDatabase.LastTopVisibleGroup = ReadUuid(xr);
					else if(xr.Name == ElemBinaries)
						return SwitchContext(ctx, KdbContext.Binaries, xr);
					else if(xr.Name == ElemCustomData)
						return SwitchContext(ctx, KdbContext.CustomData, xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.MemoryProtection:
					if(xr.Name == ElemProtTitle)
						m_pwDatabase.MemoryProtection.ProtectTitle = ReadBool(xr, false);
					else if(xr.Name == ElemProtUserName)
						m_pwDatabase.MemoryProtection.ProtectUserName = ReadBool(xr, false);
					else if(xr.Name == ElemProtPassword)
						m_pwDatabase.MemoryProtection.ProtectPassword = ReadBool(xr, true);
					else if(xr.Name == ElemProtUrl)
						m_pwDatabase.MemoryProtection.ProtectUrl = ReadBool(xr, false);
					else if(xr.Name == ElemProtNotes)
						m_pwDatabase.MemoryProtection.ProtectNotes = ReadBool(xr, false);
					// else if(xr.Name == ElemProtAutoHide)
					//	m_pwDatabase.MemoryProtection.AutoEnableVisualHiding = ReadBool(xr, true);
					else ReadUnknown(xr);
					break;

				case KdbContext.CustomIcons:
					if(xr.Name == ElemCustomIconItem)
						return SwitchContext(ctx, KdbContext.CustomIcon, xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.CustomIcon:
					if(xr.Name == ElemCustomIconItemID)
						m_uuidCustomIconID = ReadUuid(xr);
					else if(xr.Name == ElemCustomIconItemData)
					{
						string strData = ReadString(xr);
						if(!string.IsNullOrEmpty(strData))
							m_pbCustomIconData = Convert.FromBase64String(strData);
						else { Debug.Assert(false); }
					}
					else ReadUnknown(xr);
					break;

				case KdbContext.Binaries:
					if(xr.Name == ElemBinary)
					{
						if(xr.MoveToAttribute(AttrId))
						{
							string strKey = xr.Value;
							ProtectedBinary pbData = ReadProtectedBinary(xr);

							m_dictBinPool[strKey ?? string.Empty] = pbData;
						}
						else ReadUnknown(xr);
					}
					else ReadUnknown(xr);
					break;

				case KdbContext.CustomData:
					if(xr.Name == ElemStringDictExItem)
						return SwitchContext(ctx, KdbContext.CustomDataItem, xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.CustomDataItem:
					if(xr.Name == ElemKey)
						m_strCustomDataKey = ReadString(xr);
					else if(xr.Name == ElemValue)
						m_strCustomDataValue = ReadString(xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.Root:
					if(xr.Name == ElemGroup)
					{
						Debug.Assert(m_ctxGroups.Count == 0);
						if(m_ctxGroups.Count != 0) throw new FormatException();

						m_pwDatabase.RootGroup = new PwGroup(false, false);
						m_ctxGroups.Push(m_pwDatabase.RootGroup);
						m_ctxGroup = m_ctxGroups.Peek();

						return SwitchContext(ctx, KdbContext.Group, xr);
					}
					else if(xr.Name == ElemDeletedObjects)
						return SwitchContext(ctx, KdbContext.RootDeletedObjects, xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.Group:
					if(xr.Name == ElemUuid)
						m_ctxGroup.Uuid = ReadUuid(xr);
					else if(xr.Name == ElemName)
						m_ctxGroup.Name = ReadString(xr);
					else if(xr.Name == ElemNotes)
						m_ctxGroup.Notes = ReadString(xr);
					else if(xr.Name == ElemIcon)
						m_ctxGroup.IconId = (PwIcon)ReadInt(xr, (int)PwIcon.Folder);
					else if(xr.Name == ElemCustomIconID)
						m_ctxGroup.CustomIconUuid = ReadUuid(xr);
					else if(xr.Name == ElemTimes)
						return SwitchContext(ctx, KdbContext.GroupTimes, xr);
					else if(xr.Name == ElemIsExpanded)
						m_ctxGroup.IsExpanded = ReadBool(xr, true);
					else if(xr.Name == ElemGroupDefaultAutoTypeSeq)
						m_ctxGroup.DefaultAutoTypeSequence = ReadString(xr);
					else if(xr.Name == ElemEnableAutoType)
						m_ctxGroup.EnableAutoType = StrUtil.StringToBoolEx(ReadString(xr));
					else if(xr.Name == ElemEnableSearching)
						m_ctxGroup.EnableSearching = StrUtil.StringToBoolEx(ReadString(xr));
					else if(xr.Name == ElemLastTopVisibleEntry)
						m_ctxGroup.LastTopVisibleEntry = ReadUuid(xr);
					else if(xr.Name == ElemGroup)
					{
						m_ctxGroup = new PwGroup(false, false);
						m_ctxGroups.Peek().AddGroup(m_ctxGroup, true);

						m_ctxGroups.Push(m_ctxGroup);

						return SwitchContext(ctx, KdbContext.Group, xr);
					}
					else if(xr.Name == ElemEntry)
					{
						m_ctxEntry = new PwEntry(false, false);
						m_ctxGroup.AddEntry(m_ctxEntry, true);

						m_bEntryInHistory = false;
						return SwitchContext(ctx, KdbContext.Entry, xr);
					}
					else ReadUnknown(xr);
					break;

				case KdbContext.Entry:
					if(xr.Name == ElemUuid)
						m_ctxEntry.Uuid = ReadUuid(xr);
					else if(xr.Name == ElemIcon)
						m_ctxEntry.IconId = (PwIcon)ReadInt(xr, (int)PwIcon.Key);
					else if(xr.Name == ElemCustomIconID)
						m_ctxEntry.CustomIconUuid = ReadUuid(xr);
					else if(xr.Name == ElemFgColor)
					{
						string strColor = ReadString(xr);
						if(!string.IsNullOrEmpty(strColor))
							m_ctxEntry.ForegroundColor = ColorTranslator.FromHtml(strColor);
					}
					else if(xr.Name == ElemBgColor)
					{
						string strColor = ReadString(xr);
						if(!string.IsNullOrEmpty(strColor))
							m_ctxEntry.BackgroundColor = ColorTranslator.FromHtml(strColor);
					}
					else if(xr.Name == ElemOverrideUrl)
						m_ctxEntry.OverrideUrl = ReadString(xr);
					else if(xr.Name == ElemTags)
						m_ctxEntry.Tags = StrUtil.StringToTags(ReadString(xr));
					else if(xr.Name == ElemTimes)
						return SwitchContext(ctx, KdbContext.EntryTimes, xr);
					else if(xr.Name == ElemString)
						return SwitchContext(ctx, KdbContext.EntryString, xr);
					else if(xr.Name == ElemBinary)
						return SwitchContext(ctx, KdbContext.EntryBinary, xr);
					else if(xr.Name == ElemAutoType)
						return SwitchContext(ctx, KdbContext.EntryAutoType, xr);
					else if(xr.Name == ElemHistory)
					{
						Debug.Assert(m_bEntryInHistory == false);

						if(m_bEntryInHistory == false)
						{
							m_ctxHistoryBase = m_ctxEntry;
							return SwitchContext(ctx, KdbContext.EntryHistory, xr);
						}
						else ReadUnknown(xr);
					}
					else ReadUnknown(xr);
					break;

				case KdbContext.GroupTimes:
				case KdbContext.EntryTimes:
					ITimeLogger tl = ((ctx == KdbContext.GroupTimes) ?
						(ITimeLogger)m_ctxGroup : (ITimeLogger)m_ctxEntry);
					Debug.Assert(tl != null);

					if(xr.Name == ElemCreationTime)
						tl.CreationTime = ReadTime(xr);
					else if(xr.Name == ElemLastModTime)
						tl.LastModificationTime = ReadTime(xr);
					else if(xr.Name == ElemLastAccessTime)
						tl.LastAccessTime = ReadTime(xr);
					else if(xr.Name == ElemExpiryTime)
						tl.ExpiryTime = ReadTime(xr);
					else if(xr.Name == ElemExpires)
						tl.Expires = ReadBool(xr, false);
					else if(xr.Name == ElemUsageCount)
						tl.UsageCount = ReadULong(xr, 0);
					else if(xr.Name == ElemLocationChanged)
						tl.LocationChanged = ReadTime(xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.EntryString:
					if(xr.Name == ElemKey)
						m_ctxStringName = ReadString(xr);
					else if(xr.Name == ElemValue)
						m_ctxStringValue = ReadProtectedString(xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.EntryBinary:
					if(xr.Name == ElemKey)
						m_ctxBinaryName = ReadString(xr);
					else if(xr.Name == ElemValue)
						m_ctxBinaryValue = ReadProtectedBinary(xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.EntryAutoType:
					if(xr.Name == ElemAutoTypeEnabled)
						m_ctxEntry.AutoType.Enabled = ReadBool(xr, true);
					else if(xr.Name == ElemAutoTypeObfuscation)
						m_ctxEntry.AutoType.ObfuscationOptions =
							(AutoTypeObfuscationOptions)ReadInt(xr, 0);
					else if(xr.Name == ElemAutoTypeDefaultSeq)
						m_ctxEntry.AutoType.DefaultSequence = ReadString(xr);
					else if(xr.Name == ElemAutoTypeItem)
						return SwitchContext(ctx, KdbContext.EntryAutoTypeItem, xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.EntryAutoTypeItem:
					if(xr.Name == ElemWindow)
						m_ctxATName = ReadString(xr);
					else if(xr.Name == ElemKeystrokeSequence)
						m_ctxATSeq = ReadString(xr);
					else ReadUnknown(xr);
					break;

				case KdbContext.EntryHistory:
					if(xr.Name == ElemEntry)
					{
						m_ctxEntry = new PwEntry(false, false);
						m_ctxHistoryBase.History.Add(m_ctxEntry);

						m_bEntryInHistory = true;
						return SwitchContext(ctx, KdbContext.Entry, xr);
					}
					else ReadUnknown(xr);
					break;

				case KdbContext.RootDeletedObjects:
					if(xr.Name == ElemDeletedObject)
					{
						m_ctxDeletedObject = new PwDeletedObject();
						m_pwDatabase.DeletedObjects.Add(m_ctxDeletedObject);

						return SwitchContext(ctx, KdbContext.DeletedObject, xr);
					}
					else ReadUnknown(xr);
					break;

				case KdbContext.DeletedObject:
					if(xr.Name == ElemUuid)
						m_ctxDeletedObject.Uuid = ReadUuid(xr);
					else if(xr.Name == ElemDeletionTime)
						m_ctxDeletedObject.DeletionTime = ReadTime(xr);
					else ReadUnknown(xr);
					break;

				default:
					ReadUnknown(xr);
					break;
			}

			return ctx;
		}
예제 #29
0
파일: SelfTest.cs 프로젝트: Stoom/KeePass
		private static void TestProtectedObjects()
		{
#if DEBUG
			Encoding enc = StrUtil.Utf8;

			byte[] pbData = enc.GetBytes("Test Test Test Test");
			ProtectedBinary pb = new ProtectedBinary(true, pbData);
			if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-1");

			byte[] pbDec = pb.ReadData();
			if(!MemUtil.ArraysEqual(pbData, pbDec))
				throw new SecurityException("ProtectedBinary-2");
			if(!pb.IsProtected) throw new SecurityException("ProtectedBinary-3");

			byte[] pbData2 = enc.GetBytes("Test Test Test Test");
			byte[] pbData3 = enc.GetBytes("Test Test Test Test Test");
			ProtectedBinary pb2 = new ProtectedBinary(true, pbData2);
			ProtectedBinary pb3 = new ProtectedBinary(true, pbData3);
			if(!pb.Equals(pb2)) throw new SecurityException("ProtectedBinary-4");
			if(pb.Equals(pb3)) throw new SecurityException("ProtectedBinary-5");
			if(pb2.Equals(pb3)) throw new SecurityException("ProtectedBinary-6");

			if(pb.GetHashCode() != pb2.GetHashCode())
				throw new SecurityException("ProtectedBinary-7");
			if(!((object)pb).Equals((object)pb2))
				throw new SecurityException("ProtectedBinary-8");
			if(((object)pb).Equals((object)pb3))
				throw new SecurityException("ProtectedBinary-9");
			if(((object)pb2).Equals((object)pb3))
				throw new SecurityException("ProtectedBinary-10");

			ProtectedString ps = new ProtectedString();
			if(ps.Length != 0) throw new SecurityException("ProtectedString-1");
			if(!ps.IsEmpty) throw new SecurityException("ProtectedString-2");
			if(ps.ReadString().Length != 0)
				throw new SecurityException("ProtectedString-3");

			ps = new ProtectedString(true, "Test");
			ProtectedString ps2 = new ProtectedString(true, enc.GetBytes("Test"));
			if(ps.IsEmpty) throw new SecurityException("ProtectedString-4");
			pbData = ps.ReadUtf8();
			pbData2 = ps2.ReadUtf8();
			if(!MemUtil.ArraysEqual(pbData, pbData2))
				throw new SecurityException("ProtectedString-5");
			if(pbData.Length != 4)
				throw new SecurityException("ProtectedString-6");
			if(ps.ReadString() != ps2.ReadString())
				throw new SecurityException("ProtectedString-7");
			pbData = ps.ReadUtf8();
			pbData2 = ps2.ReadUtf8();
			if(!MemUtil.ArraysEqual(pbData, pbData2))
				throw new SecurityException("ProtectedString-8");
			if(!ps.IsProtected) throw new SecurityException("ProtectedString-9");
			if(!ps2.IsProtected) throw new SecurityException("ProtectedString-10");

			Random r = new Random();
			string str = string.Empty;
			ps = new ProtectedString();
			for(int i = 0; i < 100; ++i)
			{
				bool bProt = ((r.Next() % 4) != 0);
				ps = ps.WithProtection(bProt);

				int x = r.Next(str.Length + 1);
				int c = r.Next(20);
				char ch = (char)r.Next(1, 256);

				string strIns = new string(ch, c);
				str = str.Insert(x, strIns);
				ps = ps.Insert(x, strIns);

				if(ps.IsProtected != bProt)
					throw new SecurityException("ProtectedString-11");
				if(ps.ReadString() != str)
					throw new SecurityException("ProtectedString-12");

				ps = ps.WithProtection(bProt);

				x = r.Next(str.Length);
				c = r.Next(str.Length - x + 1);

				str = str.Remove(x, c);
				ps = ps.Remove(x, c);

				if(ps.IsProtected != bProt)
					throw new SecurityException("ProtectedString-13");
				if(ps.ReadString() != str)
					throw new SecurityException("ProtectedString-14");
			}
#endif
		}
예제 #30
0
        private bool GetSelBin(out string strDataItem, out ProtectedBinary pb)
        {
            strDataItem = null;
            pb = null;

            ListView.SelectedListViewItemCollection lvsic = m_lvBinaries.SelectedItems;
            if((lvsic == null) || (lvsic.Count != 1)) return false; // No assert

            strDataItem = lvsic[0].Text;
            pb = m_vBinaries.Get(strDataItem);
            if(pb == null) { Debug.Assert(false); return false; }

            return true;
        }