public bool Upgrade(SecretsManager sman, Vault vault, string password) { // Convert JSON strings and byte arrays to plain values foreach (var key in new List <string>(sman.Keys)) { sman.DefaultSerializer = new Utf8JsonSerializer(); sman.TryGetValue(key, out byte[] bytes); try { var s = Encoding.UTF8.GetString(bytes); var o = JsonConvert.DeserializeObject(s); if (o is string stringValue) { sman.Set(key, stringValue); } else if (o is byte[] byteValue) { sman.Set(key, byteValue); } } catch { throw new VaultVersionException($"Cannot upgrade secret {key}"); } } sman.CreateSentinel(); return(true); }
public bool Upgrade(SecretsManager sman, Vault vault, string password) { // Upgrade from 10,000 PBKDF2 rounds to 256,000 PBKDF2 rounds if (password is null) { return(true); } // Load old key var oldKey = SecretsManager.DerivePassword(password, vault.IV, 10000); sman.SplitAndLoadKey(oldKey); var secrets = new Dictionary <string, SecureBuffer>(vault.Data.Count); foreach (var kv in vault.Data) { secrets.Add(kv.Key, sman.Decrypt(kv.Value)); } // Load new key with explicit IV length vault.IV = new byte[16]; SecretsManager.GenerateBytes(vault.IV); var newKey = SecretsManager.DerivePassword(password, vault.IV, 256000); sman.SplitAndLoadKey(newKey); // Update individual secrets foreach (var kv in secrets) { sman.Set(kv.Key, kv.Value); kv.Value.Dispose(); } // Update sentinel to match new password vault.Sentinel = null; sman.CreateSentinel(); return(true); }