Beispiel #1
0
        private PwGroup ConvertGroup(PwGroupV3 groupV3)
        {
            PwGroup pwGroup = new PwGroup(true, false);

            pwGroup.Uuid = CreateUuidFromGroupId(groupV3.Id.Id);

            //check if we have group data for this group already (from loading in a previous pass).
            //then use the same UUID (important for merging)
            var gdForGroup = _groupData.Where(g => g.Value.Id == groupV3.Id.Id).ToList();

            if (gdForGroup.Count == 1)
            {
                pwGroup.Uuid = gdForGroup.Single().Key;
            }

            pwGroup.Name = groupV3.Name;
            Android.Util.Log.Debug("KP2A", "load kdb: group " + groupV3.Name);
            pwGroup.CreationTime         = ConvertTime(groupV3.TCreation);
            pwGroup.LastAccessTime       = ConvertTime(groupV3.TLastAccess);
            pwGroup.LastModificationTime = ConvertTime(groupV3.TLastMod);
            pwGroup.ExpiryTime           = ConvertTime(groupV3.TExpire);
            pwGroup.Expires = !(Math.Abs((pwGroup.ExpiryTime - _expireNever).TotalMilliseconds) < 500);;

            if (groupV3.Icon != null)
            {
                pwGroup.IconId = (PwIcon)groupV3.Icon.IconId;
            }
            _groupData[pwGroup.Uuid] = new AdditionalGroupData
            {
                Flags = groupV3.Flags,
                Id    = groupV3.Id.Id
            };


            for (int i = 0; i < groupV3.ChildGroups.Count; i++)
            {
                pwGroup.AddGroup(ConvertGroup(groupV3.GetGroupAt(i)), true);
            }
            for (int i = 0; i < groupV3.ChildEntries.Count; i++)
            {
                var entry = groupV3.GetEntryAt(i);
                if (entry.IsMetaStream)
                {
                    _metaStreams.Add(entry);
                    continue;
                }

                pwGroup.AddEntry(ConvertEntry(entry), true);
            }

            return(pwGroup);
        }
Beispiel #2
0
        private PwGroupV3 ConvertGroup(PwGroup fromGroup, PwDatabaseV3 dbTo)
        {
            PwGroupV3 toGroup = new PwGroupV3();

            toGroup.Name = fromGroup.Name;
            //todo remove
            Android.Util.Log.Debug("KP2A", "save kdb: group " + fromGroup.Name);

            toGroup.TCreation   = new PwDate(ConvertTime(fromGroup.CreationTime));
            toGroup.TLastAccess = new PwDate(ConvertTime(fromGroup.LastAccessTime));
            toGroup.TLastMod    = new PwDate(ConvertTime(fromGroup.LastModificationTime));
            if (fromGroup.Expires)
            {
                toGroup.TExpire = new PwDate(ConvertTime(fromGroup.ExpiryTime));
            }
            else
            {
                toGroup.TExpire = new PwDate(ConvertTime(_expireNever));
            }

            toGroup.Icon = dbTo.IconFactory.GetIcon((int)fromGroup.IconId);
            AdditionalGroupData groupData;

            if (_groupData.TryGetValue(fromGroup.Uuid, out groupData))
            {
                toGroup.Id    = new PwGroupIdV3(groupData.Id);
                toGroup.Flags = groupData.Flags;
            }
            else
            {
                //group was added
                do
                {
                    toGroup.Id = new PwGroupIdV3(new Random().Next());
                } while (_groupData.Values.Any(gd => gd.Id == toGroup.Id.Id));                 //retry if id already exists
                //store to block new id and reuse when saving again (without loading in between)
                _groupData[fromGroup.Uuid] = new AdditionalGroupData
                {
                    Id = toGroup.Id.Id
                };
            }

            return(toGroup);
        }
Beispiel #3
0
        private void AssignParent(PwGroup kpParent, PwDatabaseV3 dbV3, Dictionary <int, PwGroupV3> groupV3s)
        {
            PwGroupV3 parentV3;

            if (kpParent.ParentGroup == null)
            {
                parentV3 = dbV3.RootGroup;
            }
            else
            {
                parentV3 = groupV3s[_groupData[kpParent.Uuid].Id];
            }

            foreach (PwGroup g in kpParent.Groups.OrderBy(g => g.Name))
            {
                PwGroupV3 groupV3 = groupV3s[_groupData[g.Uuid].Id];

                parentV3.ChildGroups.Add(groupV3);
                groupV3.Parent = parentV3;

                AssignParent(g, dbV3, groupV3s);
            }
        }
Beispiel #4
0
        private PwGroup ConvertGroup(PwGroupV3 groupV3)
        {
            PwGroup pwGroup = new PwGroup(true, false);
            pwGroup.Uuid = CreateUuidFromGroupId(groupV3.Id.Id);

            //check if we have group data for this group already (from loading in a previous pass).
            //then use the same UUID (important for merging)
            var gdForGroup = _groupData.Where(g => g.Value.Id == groupV3.Id.Id).ToList();
            if (gdForGroup.Count == 1)
            {
                pwGroup.Uuid = gdForGroup.Single().Key;
            }

            pwGroup.Name = groupV3.Name;
            Android.Util.Log.Debug("KP2A", "load kdb: group " + groupV3.Name);
            pwGroup.CreationTime = ConvertTime(groupV3.TCreation);
            pwGroup.LastAccessTime = ConvertTime(groupV3.TLastAccess);
            pwGroup.LastModificationTime = ConvertTime(groupV3.TLastMod);
            pwGroup.ExpiryTime = ConvertTime(groupV3.TExpire);
            pwGroup.Expires = !(Math.Abs((pwGroup.ExpiryTime - _expireNever).TotalMilliseconds) < 500); ;

            if (groupV3.Icon != null)
                pwGroup.IconId = (PwIcon) groupV3.Icon.IconId;
            _groupData[pwGroup.Uuid] = new AdditionalGroupData
                {
                    Flags = groupV3.Flags,
                    Id = groupV3.Id.Id
                };

            for (int i = 0; i < groupV3.ChildGroups.Count;i++)
            {
                pwGroup.AddGroup(ConvertGroup(groupV3.GetGroupAt(i)), true);
            }
            for (int i = 0; i < groupV3.ChildEntries.Count; i++)
            {
                var entry = groupV3.GetEntryAt(i);
                if (entry.IsMetaStream)
                {
                    _metaStreams.Add(entry);
                    continue;
                }

                pwGroup.AddEntry(ConvertEntry(entry), true);
            }

            return pwGroup;
        }
Beispiel #5
0
        private PwGroupV3 ConvertGroup(PwGroup fromGroup, PwDatabaseV3 dbTo)
        {
            PwGroupV3 toGroup = new PwGroupV3();
            toGroup.Name = fromGroup.Name;
            //todo remove
            Android.Util.Log.Debug("KP2A", "save kdb: group " + fromGroup.Name);

            toGroup.TCreation = new PwDate(ConvertTime(fromGroup.CreationTime));
            toGroup.TLastAccess= new PwDate(ConvertTime(fromGroup.LastAccessTime));
            toGroup.TLastMod = new PwDate(ConvertTime(fromGroup.LastModificationTime));
            if (fromGroup.Expires)
            {
                toGroup.TExpire = new PwDate(ConvertTime(fromGroup.ExpiryTime));
            }
            else
            {
                toGroup.TExpire = new PwDate(ConvertTime(_expireNever));
            }

            toGroup.Icon = dbTo.IconFactory.GetIcon((int) fromGroup.IconId);
            AdditionalGroupData groupData;
            if (_groupData.TryGetValue(fromGroup.Uuid, out groupData))
            {
                toGroup.Id = new PwGroupIdV3(groupData.Id);
                toGroup.Flags = groupData.Flags;
            }
            else
            {
                //group was added
                do
                {
                    toGroup.Id = new PwGroupIdV3(new Random().Next());
                } while (_groupData.Values.Any(gd => gd.Id == toGroup.Id.Id)); //retry if id already exists
                //store to block new id and reuse when saving again (without loading in between)
                _groupData[fromGroup.Uuid] = new AdditionalGroupData
                    {
                        Id = toGroup.Id.Id
                    };

            }

            return toGroup;
        }
Beispiel #6
0
        public void Save(PwDatabase kpDatabase, Stream stream)
        {
            PwDatabaseV3 db       = new PwDatabaseV3();
            KcpPassword  pwd      = kpDatabase.MasterKey.GetUserKey <KcpPassword>();
            string       password = pwd != null?pwd.Password.ReadString() : "";

            KcpKeyFile keyfile         = kpDatabase.MasterKey.GetUserKey <KcpKeyFile>();
            Stream     keyfileContents = null;

            if (keyfile != null)
            {
                keyfileContents = new MemoryStream(keyfile.RawFileData.ReadData());
            }
            db.SetMasterKey(password, keyfileContents);

            AesKdf kdf = new AesKdf();

            if (!kdf.Uuid.Equals(kpDatabase.KdfParameters.KdfUuid))
            {
                db.NumRounds = (uint)PwDefs.DefaultKeyEncryptionRounds;
            }
            else
            {
                ulong uRounds = kpDatabase.KdfParameters.GetUInt64(
                    AesKdf.ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
                uRounds = Math.Min(uRounds, 0xFFFFFFFEUL);

                db.NumRounds = (uint)uRounds;
            }


            db.Name = kpDatabase.Name;
            if (kpDatabase.DataCipherUuid.Equals(StandardAesEngine.AesUuid))
            {
                db.Algorithm = PwEncryptionAlgorithm.Rjindal;
            }
            else
            {
                db.Algorithm = PwEncryptionAlgorithm.Twofish;
            }

            //create groups
            db.Groups.Clear();
            var fromGroups = kpDatabase.RootGroup.GetGroups(true);
            Dictionary <int, PwGroupV3> groupV3s = new Dictionary <int, PwGroupV3>(fromGroups.Count());

            foreach (PwGroup g in fromGroups)
            {
                if (g == kpDatabase.RootGroup)
                {
                    continue;
                }
                PwGroupV3 groupV3 = ConvertGroup(g, db);
                db.Groups.Add(groupV3);
                groupV3s[groupV3.Id.Id] = groupV3;
            }

            //traverse again and assign parents
            db.RootGroup       = ConvertGroup(kpDatabase.RootGroup, db);
            db.RootGroup.Level = -1;

            AssignParent(kpDatabase.RootGroup, db, groupV3s);

            foreach (PwEntry e in kpDatabase.RootGroup.GetEntries(true))
            {
                PwEntryV3 entryV3 = ConvertEntry(e, db);
                entryV3.Parent = groupV3s[_groupData[e.ParentGroup.Uuid].Id];
                entryV3.Parent.ChildEntries.Add(entryV3);
                entryV3.GroupId = entryV3.Parent.Id.Id;
                db.Entries.Add(entryV3);
            }

            //add meta stream entries:
            if (db.Groups.Any())
            {
                foreach (var metaEntry in _metaStreams)
                {
                    metaEntry.GroupId = db.Groups.First().Id.Id;
                    db.Entries.Add(metaEntry);
                }
            }


            HashingStreamEx hashedStream = new HashingStreamEx(stream, true, null);
            PwDbV3Output    output       = new PwDbV3Output(db, hashedStream);

            output.Output();
            hashedStream.Close();
            HashOfLastStream = hashedStream.Hash;

            kpDatabase.HashOfLastIO = kpDatabase.HashOfFileOnDisk = HashOfLastStream;
            stream.Close();
        }