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"); AesKdf kdf = new AesKdf(); KdfParameters p = kdf.GetDefaultParameters(); p.SetUInt64(AesKdf.ParamRounds, uNumRounds); p.SetByteArray(AesKdf.ParamSeed, pbKeySeed32); return GenerateKey32(p); }
public override bool Export(PwExportInfo pwExportInfo, Stream sOutput, IStatusLogger slLogger) { PwDatabase pd = pwExportInfo.ContextDatabase; PwGroup pgRoot = pwExportInfo.DataGroup; // Remove everything that requires KDBX 4 or higher; // see also KdbxFile.GetMinKdbxVersion KdfParameters pKdf = pd.KdfParameters; AesKdf kdfAes = new AesKdf(); if(!kdfAes.Uuid.Equals(pKdf.KdfUuid)) pd.KdfParameters = kdfAes.GetDefaultParameters(); VariantDictionary vdPublic = pd.PublicCustomData; pd.PublicCustomData = new VariantDictionary(); List<PwGroup> lCustomGK = new List<PwGroup>(); List<StringDictionaryEx> lCustomGV = new List<StringDictionaryEx>(); List<PwEntry> lCustomEK = new List<PwEntry>(); List<StringDictionaryEx> lCustomEV = new List<StringDictionaryEx>(); GroupHandler gh = delegate(PwGroup pg) { if(pg == null) { Debug.Assert(false); return true; } if(pg.CustomData.Count > 0) { lCustomGK.Add(pg); lCustomGV.Add(pg.CustomData); pg.CustomData = new StringDictionaryEx(); } return true; }; EntryHandler eh = delegate(PwEntry pe) { if(pe == null) { Debug.Assert(false); return true; } if(pe.CustomData.Count > 0) { lCustomEK.Add(pe); lCustomEV.Add(pe.CustomData); pe.CustomData = new StringDictionaryEx(); } return true; }; gh(pgRoot); pgRoot.TraverseTree(TraversalMethod.PreOrder, gh, eh); try { KdbxFile kdbx = new KdbxFile(pd); kdbx.ForceVersion = KdbxFile.FileVersion32_3; kdbx.Save(sOutput, pgRoot, KdbxFormat.Default, slLogger); } finally { // Restore pd.KdfParameters = pKdf; pd.PublicCustomData = vdPublic; for(int i = 0; i < lCustomGK.Count; ++i) lCustomGK[i].CustomData = lCustomGV[i]; for(int i = 0; i < lCustomEK.Count; ++i) lCustomEK[i].CustomData = lCustomEV[i]; } return true; }
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; }