Inheritance: ScriptSecrets
        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);
        }
Example #3
0
        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));
        }
Example #4
0
        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);
        }
Example #7
0
        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;
        }
Example #10
0
 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);
 }
Example #11
0
        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);
        }
Example #15
0
        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);
        }