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; } }
/// <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; } }
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); }
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); }
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; }
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); }
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); }
/// <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); }
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); }
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); } } } }
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(); } }
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(); }
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); }
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); }
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 }
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); }
/// <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; }
public KcpUserAccount(byte[] pbKey) { //byte[] pbDummyData = new byte[128]; //ProtectedData.Protect(pbDummyData, m_pbEntropy, // DataProtectionScope.CurrentUser); m_pbKeyData = new ProtectedBinary(true, pbKey); }
/// <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; }
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); }
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); } }
/// <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; } }
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; }
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 }
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; }