Example #1
0
        public GetPassword GetPasswordGetter(string password)
        {
            var hasher   = new HasherV2(password);
            var getgenpw = new PasswordGenerator(hasher.Hash, new StringifierV1().Stringify);
            var getaeppw = new PasswordGenerator(hasher.Hash, new StringifierVaep().Stringify);

            return(entry => {
                if (entry is StoredEntry stored)
                {
                    return stored.password;
                }

                if (entry is GeneratedEntry gen)
                {
                    if (GENERATED_PFP_TYPE.Equals(gen.type))
                    {
                        return getgenpw.Get(gen);
                    }
                    else if (GENERATED_AEP_TYPE.Equals(gen.type))
                    {
                        return getaeppw.Get(gen);
                    }
                }

                throw new ArgumentException($"Unsupported entry for {entry.name}@{entry.site}");
            });
        }
        public IList <BaseEntry> Load(Stream stream, string password)
        {
            var json = new JsonConvert();

            var reader = new StreamReader(stream);
            var backup = json.Deserialize <DeserializedBackup>(reader.ReadToEnd());

            if (!PFP_APPLICATION.Equals(backup.application))
            {
                throw new ReaderException($"Unsupported application {backup.application}");
            }

            if (!(backup.format == 2 || backup.format == 3))
            {
                throw new ReaderException($"Unsupported format version {backup.format}");
            }

            if (!(backup.data.ContainsKey(SALT_KEY) || backup.data.ContainsKey(HMAC_KEY)))
            {
                throw new ReaderException($"Invalid format");
            }

            string str;

            var hasher  = new HasherV2(password);
            var cipher  = new CipherV1(hasher.Hash, backup.data[SALT_KEY]);
            var decrypt = GetDecryptFn(cipher);

            try {
                str = decrypt(backup.data[HMAC_KEY]);
            } catch (InvalidCipherTextException e) {
                if (e.Message.Equals(MAC_MESSAGE))
                {
                    throw new ReaderException("Wrong master password");
                }
                else
                {
                    throw;
                }
            }

            backup.data.Remove(SALT_KEY);
            backup.data.Remove(HMAC_KEY);

            var result = new List <BaseEntry>();

            foreach (var item in backup.data)
            {
                if (!item.Key.StartsWith(STORAGE_PREFIX))
                {
                    continue;
                }

                str = decrypt(item.Value);
                result.Add(json.Deserialize <BaseEntry>(str));
            }

            return(result);
        }
        public void Save(Stream stream, string password, IList <BaseEntry> entries)
        {
            var backup = new DeserializedBackup {
                application = PFP_APPLICATION,
                format      = 2,
                data        = new Dictionary <string, string>()
            };

            entries = Util.GenerateSiteEntries(entries);

            var salt = Util.GenerateRandom(SALT_LENGTH);
            var hmac = Util.GenerateRandom(HMAC_LENGTH);

            var json    = new JsonConvert();
            var hasher  = new HasherV2(password);
            var digest  = new DigesterV1(hmac);
            var cipher  = new CipherV1(hasher.Hash, salt);
            var encrypt = GetEncryptFn(cipher);

            backup.data.Add(SALT_KEY, salt);
            backup.data.Add(HMAC_KEY, encrypt(json.Serialize(hmac)));

            foreach (var entry in entries)
            {
                var data = encrypt(json.Serialize(entry));

                var key = STORAGE_PREFIX + digest.Digest(entry.site);

                if (entry is PassEntry pass)
                {
                    key += ":" + digest.Digest(pass.site + "\0" + pass.name + "\0" + pass.revision);
                }

                backup.data.Add(key, data);
            }

            var writer = new StreamWriter(stream);
            var str    = json.Serialize(backup);

            writer.Write(str);
            writer.Flush();
        }