public virtual HostSecrets GetHostSecrets() { if (_hostSecrets == null) { string secretFilePath = Path.Combine(_secretsPath, ScriptConstants.HostMetadataFileName); if (File.Exists(secretFilePath)) { // load the secrets file string secretsJson = File.ReadAllText(secretFilePath); _hostSecrets = JsonConvert.DeserializeObject <HostSecrets>(secretsJson); } else { // initialize with new secrets and save it _hostSecrets = new HostSecrets { MasterKey = GenerateSecretString(), FunctionKey = GenerateSecretString() }; File.WriteAllText(secretFilePath, JsonConvert.SerializeObject(_hostSecrets, Formatting.Indented)); } } return(_hostSecrets); }
public async virtual Task <HostSecretsInfo> GetHostSecretsAsync() { if (_hostSecrets == null) { HostSecrets hostSecrets = await LoadSecretsAsync <HostSecrets>(); if (hostSecrets == null) { _traceWriter.Verbose(Resources.TraceHostSecretGeneration); hostSecrets = GenerateHostSecrets(); await PersistSecretsAsync(hostSecrets); } // Host secrets will be in the original persisted state at this point (e.g. encrypted), // so we read the secrets running them through the appropriate readers hostSecrets = ReadHostSecrets(hostSecrets); // If the persistence state of any of our secrets is stale (e.g. the encryption key has been rotated), update // the state and persist the secrets if (hostSecrets.HasStaleKeys) { _traceWriter.Verbose(Resources.TraceStaleHostSecretRefresh); await RefreshSecretsAsync(hostSecrets); } _hostSecrets = new HostSecretsInfo { MasterKey = hostSecrets.MasterKey.Value, FunctionKeys = hostSecrets.FunctionKeys.ToDictionary(s => s.Name, s => s.Value) }; } return(_hostSecrets); }
public async Task <KeyOperationResult> SetMasterKeyAsync(string value = null) { HostSecrets secrets = await LoadSecretsAsync <HostSecrets>(); if (secrets == null) { secrets = GenerateHostSecrets(); } OperationResult result; string masterKey; if (value == null) { // Generate a new secret (clear) masterKey = GenerateSecret(); result = OperationResult.Created; } else { // Use the provided secret masterKey = value; result = OperationResult.Updated; } // Creates a key with the new master key (which will be encrypted, if required) secrets.MasterKey = CreateKey(ScriptConstants.DefaultMasterKeyName, masterKey); await PersistSecretsAsync(secrets); _logger.LogInformation(string.Format(Resources.TraceMasterKeyCreatedOrUpdated, result)); return(new KeyOperationResult(masterKey, result)); }
private async Task <ScriptSecrets> ReadHostSecrets() { IDictionary <string, string> secrets = await _kubernetesClient.GetSecrets(); HostSecrets hostSecrets = new HostSecrets() { FunctionKeys = new List <Key>(), SystemKeys = new List <Key>() }; foreach (var pair in secrets) { if (pair.Key.StartsWith(MasterKey)) { hostSecrets.MasterKey = new Key("master", pair.Value); } else if (pair.Key.StartsWith(HostFunctionKeyPrefix)) { hostSecrets.FunctionKeys.Add(ParseKeyWithPrefix(HostFunctionKeyPrefix, pair.Key, pair.Value)); } else if (pair.Key.StartsWith(SystemKeyPrefix)) { hostSecrets.SystemKeys.Add(ParseKeyWithPrefix(SystemKeyPrefix, pair.Key, pair.Value)); } } return(hostSecrets?.MasterKey == null ? null : hostSecrets); }
private HostSecrets ReadHostSecrets(HostSecrets hostSecrets) { return(new HostSecrets { MasterKey = _keyValueConverterFactory.ReadKey(hostSecrets.MasterKey), FunctionKeys = hostSecrets.FunctionKeys.Select(k => _keyValueConverterFactory.ReadKey(k)).ToList() }); }
private async Task <ScriptSecrets> ReadHostSecrets() { IPage <SecretItem> secretItems = await _keyVaultClient.Value.GetSecretsAsync(GetVaultBaseUrl()); List <Task <SecretBundle> > tasks = new List <Task <SecretBundle> >(); // Add master key task SecretItem masterItem = secretItems.FirstOrDefault(x => x.Identifier.Name.StartsWith(MasterKey)); if (masterItem != null) { tasks.Add(_keyVaultClient.Value.GetSecretAsync(GetVaultBaseUrl(), masterItem.Identifier.Name)); } else { return(null); } // Add functionKey tasks foreach (SecretItem item in secretItems.Where(x => x.Identifier.Name.StartsWith(FunctionKeyPrefix))) { tasks.Add(_keyVaultClient.Value.GetSecretAsync(GetVaultBaseUrl(), item.Identifier.Name)); } // Add systemKey tasks foreach (SecretItem item in secretItems.Where(x => x.Identifier.Name.StartsWith(SystemKeyPrefix))) { tasks.Add(_keyVaultClient.Value.GetSecretAsync(GetVaultBaseUrl(), item.Identifier.Name)); } await Task.WhenAll(tasks); HostSecrets hostSecrets = new HostSecrets() { FunctionKeys = new List <Key>(), SystemKeys = new List <Key>() }; foreach (Task <SecretBundle> task in tasks) { SecretBundle item = task.Result; if (item.SecretIdentifier.Name.StartsWith(MasterKey)) { hostSecrets.MasterKey = SecretBundleToKey(item, MasterKey); } else if (item.SecretIdentifier.Name.StartsWith(FunctionKeyPrefix)) { hostSecrets.FunctionKeys.Add(SecretBundleToKey(item, FunctionKeyPrefix)); } else if (item.SecretIdentifier.Name.StartsWith(SystemKeyPrefix)) { hostSecrets.SystemKeys.Add(SecretBundleToKey(item, SystemKeyPrefix)); } } return(hostSecrets); }
private async Task <ScriptSecrets> ReadHostSecrets() { List <IEnumerable <SecretItem> > secretsPages = await GetKeyVaultSecretsPagesAsync(_keyVaultClient.Value, GetVaultBaseUrl()); List <Task <SecretBundle> > tasks = new List <Task <SecretBundle> >(); // Add master key task List <SecretItem> masterItems = FindSecrets(secretsPages, x => x.Identifier.Name.StartsWith(MasterKey)); if (masterItems.Count > 0) { tasks.Add(_keyVaultClient.Value.GetSecretAsync(GetVaultBaseUrl(), masterItems[0].Identifier.Name)); } else { return(null); } // Add functionKey tasks foreach (SecretItem item in FindSecrets(secretsPages, x => x.Identifier.Name.StartsWith(FunctionKeyPrefix))) { tasks.Add(_keyVaultClient.Value.GetSecretAsync(GetVaultBaseUrl(), item.Identifier.Name)); } // Add systemKey tasks foreach (SecretItem item in FindSecrets(secretsPages, x => x.Identifier.Name.StartsWith(SystemKeyPrefix))) { tasks.Add(_keyVaultClient.Value.GetSecretAsync(GetVaultBaseUrl(), item.Identifier.Name)); } await Task.WhenAll(tasks); HostSecrets hostSecrets = new HostSecrets() { FunctionKeys = new List <Key>(), SystemKeys = new List <Key>() }; foreach (Task <SecretBundle> task in tasks) { SecretBundle item = task.Result; if (item.SecretIdentifier.Name.StartsWith(MasterKey)) { hostSecrets.MasterKey = SecretBundleToKey(item, MasterKey); } else if (item.SecretIdentifier.Name.StartsWith(FunctionKeyPrefix)) { hostSecrets.FunctionKeys.Add(SecretBundleToKey(item, FunctionKeyPrefix)); } else if (item.SecretIdentifier.Name.StartsWith(SystemKeyPrefix)) { hostSecrets.SystemKeys.Add(SecretBundleToKey(item, SystemKeyPrefix)); } } return(hostSecrets); }
private async Task <ScriptSecrets> ReadHostSecrets() { AsyncPageable <SecretProperties> secretsPages = GetKeyVaultSecretsPagesAsync(_secretClient.Value); List <Task <Response <KeyVaultSecret> > > tasks = new List <Task <Response <KeyVaultSecret> > >(); // Add master key task List <SecretProperties> masterItems = await FindSecrets(secretsPages, x => x.Name.StartsWith(MasterKey)); if (masterItems.Count > 0) { tasks.Add(_secretClient.Value.GetSecretAsync(masterItems[0].Name)); } else { return(null); } // Add functionKey tasks foreach (SecretProperties item in await FindSecrets(secretsPages, x => x.Name.StartsWith(FunctionKeyPrefix))) { tasks.Add(_secretClient.Value.GetSecretAsync(item.Name)); } // Add systemKey tasks foreach (SecretProperties item in await FindSecrets(secretsPages, x => x.Name.StartsWith(SystemKeyPrefix))) { tasks.Add(_secretClient.Value.GetSecretAsync(item.Name)); } await Task.WhenAll(tasks); HostSecrets hostSecrets = new HostSecrets() { FunctionKeys = new List <Key>(), SystemKeys = new List <Key>() }; foreach (Task <Response <KeyVaultSecret> > task in tasks) { KeyVaultSecret item = task.Result; if (item.Name.StartsWith(MasterKey)) { hostSecrets.MasterKey = KeyVaultSecretToKey(item, MasterKey); } else if (item.Name.StartsWith(FunctionKeyPrefix)) { hostSecrets.FunctionKeys.Add(KeyVaultSecretToKey(item, FunctionKeyPrefix)); } else if (item.Name.StartsWith(SystemKeyPrefix)) { hostSecrets.SystemKeys.Add(KeyVaultSecretToKey(item, SystemKeyPrefix)); } } return(hostSecrets); }
public override ScriptSecrets Refresh(IKeyValueConverterFactory factory) { var secrets = new HostSecrets { MasterKey = factory.WriteKey(MasterKey), FunctionKeys = FunctionKeys.Select(k => factory.WriteKey(k)).ToList() }; return secrets; }
private HostSecrets GenerateHostSecrets(HostSecrets secrets) { if (secrets.MasterKey.IsEncrypted) { secrets.MasterKey.Value = GenerateSecret(); } secrets.SystemKeys = RegenerateKeys(secrets.SystemKeys); secrets.FunctionKeys = RegenerateKeys(secrets.FunctionKeys); return(secrets); }
public override ScriptSecrets Refresh(IKeyValueConverterFactory factory) { var secrets = new HostSecrets { MasterKey = factory.WriteKey(MasterKey), FunctionKeys = FunctionKeys.Select(k => factory.WriteKey(k)).ToList() }; return(secrets); }
private void OnChanged(object sender, FileSystemEventArgs e) { // clear the cached secrets if they exist // they'll be reloaded on demand next time if (string.Compare(Path.GetFileName(e.FullPath), ScriptConstants.HostMetadataFileName, StringComparison.OrdinalIgnoreCase) == 0) { _hostSecrets = null; } else { FunctionSecrets secrets; string name = Path.GetFileNameWithoutExtension(e.FullPath).ToLowerInvariant(); _secretsMap.TryRemove(name, out secrets); } }
private static string SerializeHostSecrets(HostSecrets secrets) { // Output: // { // "masterKey" : "masterkeyvalue", // "functionKey" : "functionkeyvalue" // } var hostSecrets = new JObject { [MasterKeyPropertyName] = secrets.MasterKey.Value, [HostFunctionKeyPropertyName] = GetFunctionKeyFromCollection(secrets.FunctionKeys) }; return(hostSecrets.ToString()); }
public async virtual Task <HostSecretsInfo> GetHostSecretsAsync() { if (_hostSecrets == null) { HostSecrets hostSecrets = await LoadSecretsAsync <HostSecrets>(); if (hostSecrets == null) { // host secrets do not yet exist so generate them _logger.LogDebug(Resources.TraceHostSecretGeneration); hostSecrets = GenerateHostSecrets(); await PersistSecretsAsync(hostSecrets); } try { // Host secrets will be in the original persisted state at this point (e.g. encrypted), // so we read the secrets running them through the appropriate readers hostSecrets = ReadHostSecrets(hostSecrets); } catch (CryptographicException) { _logger?.LogDebug(Resources.TraceNonDecryptedHostSecretRefresh); await PersistSecretsAsync(hostSecrets, null, true); await RefreshSecretsAsync(hostSecrets); } // If the persistence state of any of our secrets is stale (e.g. the encryption key has been rotated), update // the state and persist the secrets if (hostSecrets.HasStaleKeys) { _logger.LogDebug(Resources.TraceStaleHostSecretRefresh); await RefreshSecretsAsync(hostSecrets); } _hostSecrets = new HostSecretsInfo { MasterKey = hostSecrets.MasterKey.Value, FunctionKeys = hostSecrets.FunctionKeys.ToDictionary(s => s.Name, s => s.Value), SystemKeys = hostSecrets.SystemKeys.ToDictionary(s => s.Name, s => s.Value) }; } return(_hostSecrets); }
public static Dictionary <string, string> GetDictionaryFromScriptSecrets(ScriptSecrets secrets, string functionName) { Dictionary <string, string> dic = new Dictionary <string, string>(); HostSecrets hostSecrets = secrets as HostSecrets; FunctionSecrets functionSecrets = secrets as FunctionSecrets; if (hostSecrets != null) { if (hostSecrets.MasterKey != null) { dic.Add(MasterKey + "master", hostSecrets.MasterKey.Value); } if (hostSecrets.FunctionKeys != null) { foreach (Key key in hostSecrets.FunctionKeys) { dic.Add($"{FunctionKeyPrefix}{Normalize(key.Name)}", key.Value); } } if (hostSecrets.SystemKeys != null) { foreach (Key key in hostSecrets.SystemKeys) { dic.Add($"{SystemKeyPrefix}{Normalize(key.Name)}", key.Value); } } } else if (functionSecrets != null) { if (functionSecrets.Keys != null) { foreach (Key key in functionSecrets.Keys) { dic.Add($"{FunctionPrefix}{Normalize(functionName)}--{Normalize(key.Name)}", key.Value); } } } return(dic); }
public void DeserializeHostSecrets_ReturnsExpectedResult() { var serializer = new ScriptSecretSerializerV0(); var serializedSecret = "{'masterKey': 'master', 'functionKey': 'master'}"; var expected = new HostSecrets { MasterKey = new Key { Name = ScriptConstants.DefaultMasterKeyName, Value = "master" }, FunctionKeys = new List<Key> { new Key { Name = ScriptConstants.DefaultFunctionKeyName, Value = "master", IsEncrypted = false } } }; HostSecrets actual = serializer.DeserializeSecrets<HostSecrets>(JObject.Parse(serializedSecret)); Assert.NotNull(actual); Assert.Equal(expected.MasterKey, actual.MasterKey); AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys); }
public void SerializeHostSecrets_ReturnsExpectedResult() { var serializer = new ScriptSecretSerializerV1(); var secrets = new HostSecrets { MasterKey = new Key { Name = "master", Value = "1234" }, FunctionKeys = new List<Key> { new Key { Name = "Key1", Value = "Value1", IsEncrypted = false }, new Key { Name = "Key2", Value = "Value2", IsEncrypted = true } } }; string serializedSecret = serializer.SerializeSecrets(secrets); var jsonObject = JObject.Parse(serializedSecret); var functionSecrets = jsonObject.Property("functionKeys")?.Value?.ToObject<List<Key>>(); var masterKey = jsonObject.Property("masterKey")?.Value?.ToObject<Key>(); Assert.NotNull(serializedSecret); Assert.Equal(secrets.MasterKey, masterKey); AssertKeyCollectionsEquality(secrets.FunctionKeys, functionSecrets); }
public void SerializeHostSecrets_ReturnsExpectedResult() { var serializer = new ScriptSecretSerializerV0(); var secrets = new HostSecrets { MasterKey = new Key { Name = "master", Value = "mastervalue" }, FunctionKeys = new List<Key> { new Key { Name = string.Empty, Value = "functionKeyValue", IsEncrypted = false, } } }; string serializedSecret = serializer.SerializeSecrets(secrets); Assert.NotNull(serializedSecret); var jsonObject = JObject.Parse(serializedSecret); var functionKey = jsonObject.Value<string>("functionKey"); var masterKey = jsonObject.Value<string>("masterKey"); Assert.Equal("mastervalue", masterKey); Assert.Equal("functionKeyValue", functionKey); }
public void DeserializeHostSecrets_ReturnsExpectedResult() { var serializer = new ScriptSecretSerializerV1(); var serializedSecret = "{'masterKey':{'name':'master','value':'1234','encrypted':false},'functionKeys':[{'name':'Key1','value':'Value1','encrypted':false},{'name':'Key2','value':'Value2','encrypted':true}]}"; var expected = new HostSecrets { MasterKey = new Key { Name = "master", Value = "1234" }, FunctionKeys = new List<Key> { new Key { Name = "Key1", Value = "Value1", IsEncrypted = false }, new Key { Name = "Key2", Value = "Value2", IsEncrypted = true } } }; HostSecrets actual = serializer.DeserializeSecrets<HostSecrets>(JObject.Parse(serializedSecret)); Assert.NotNull(actual); Assert.Equal(expected.MasterKey, actual.MasterKey); AssertKeyCollectionsEquality(expected.FunctionKeys, actual.FunctionKeys); }