Skip to content

Commit 038aed3

Browse files
alrodfabiocav
authored andcommitted
[porting to V1] Geometric key size progression during snapshotting. Fixes #3034.
1 parent 2a73a53 commit 038aed3

File tree

2 files changed

+50
-12
lines changed

2 files changed

+50
-12
lines changed

src/WebJobs.Script.WebHost/Security/SecretManager.cs

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public async virtual Task<HostSecretsInfo> GetHostSecretsAsync()
103103
_traceWriter.Verbose(Resources.TraceNonDecryptedHostSecretRefresh);
104104
_logger?.LogDebug(Resources.TraceNonDecryptedHostSecretRefresh);
105105
await PersistSecretsAsync(hostSecrets, null, true);
106+
hostSecrets = GenerateHostSecrets(hostSecrets);
106107
await RefreshSecretsAsync(hostSecrets);
107108
}
108109

@@ -157,13 +158,7 @@ public async virtual Task<IDictionary<string, string>> GetFunctionSecretsAsync(s
157158
string messageGeneratoin = string.Format(Resources.TraceFunctionSecretGeneration, functionName);
158159
_traceWriter.Info(messageGeneratoin, traceProperties);
159160
_logger?.LogInformation(messageGeneratoin);
160-
secrets = new FunctionSecrets
161-
{
162-
Keys = new List<Key>
163-
{
164-
GenerateKey(ScriptConstants.DefaultFunctionKeyName)
165-
}
166-
};
161+
secrets = GenerateFunctionSecrets();
167162

168163
await PersistSecretsAsync(secrets, functionName);
169164
}
@@ -179,6 +174,7 @@ public async virtual Task<IDictionary<string, string>> GetFunctionSecretsAsync(s
179174
_traceWriter.Info(messageNonDecrypted, traceProperties);
180175
_logger?.LogInformation(messageNonDecrypted);
181176
await PersistSecretsAsync(secrets, functionName, true);
177+
secrets = GenerateFunctionSecrets(secrets);
182178
await RefreshSecretsAsync(secrets, functionName);
183179
}
184180

@@ -417,6 +413,45 @@ private HostSecrets GenerateHostSecrets()
417413
};
418414
}
419415

416+
private static HostSecrets GenerateHostSecrets(HostSecrets secrets)
417+
{
418+
if (secrets.MasterKey.IsEncrypted)
419+
{
420+
secrets.MasterKey.Value = GenerateSecret();
421+
}
422+
secrets.SystemKeys = RegenerateKeys(secrets.SystemKeys);
423+
secrets.FunctionKeys = RegenerateKeys(secrets.FunctionKeys);
424+
return secrets;
425+
}
426+
427+
private FunctionSecrets GenerateFunctionSecrets()
428+
{
429+
return new FunctionSecrets
430+
{
431+
Keys = new List<Key>
432+
{
433+
GenerateKey(ScriptConstants.DefaultFunctionKeyName)
434+
}
435+
};
436+
}
437+
438+
private static FunctionSecrets GenerateFunctionSecrets(FunctionSecrets secrets)
439+
{
440+
secrets.Keys = RegenerateKeys(secrets.Keys);
441+
return secrets;
442+
}
443+
private static IList<Key> RegenerateKeys(IList<Key> list)
444+
{
445+
return list.Select(k =>
446+
{
447+
if (k.IsEncrypted)
448+
{
449+
k.Value = GenerateSecret();
450+
}
451+
return k;
452+
}).ToList();
453+
}
454+
420455
private Task RefreshSecretsAsync<T>(T secrets, string keyScope = null) where T : ScriptSecrets
421456
{
422457
var refreshedSecrets = secrets.Refresh(_keyValueConverterFactory);

test/WebJobs.Script.Tests/Security/SecretManagerTests.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -527,9 +527,9 @@ public async Task GetHostSecrets_WhenNonDecryptedHostSecrets_SavesAndRefreshes()
527527
}
528528

529529
Assert.NotNull(hostSecrets);
530-
Assert.Equal(hostSecrets.MasterKey, "cryptoError");
530+
Assert.NotEqual(hostSecrets.MasterKey, "cryptoError");
531531
var result = JsonConvert.DeserializeObject<HostSecrets>(File.ReadAllText(Path.Combine(directory.Path, ScriptConstants.HostMetadataFileName)));
532-
Assert.Equal(result.MasterKey.Value, "!cryptoError");
532+
Assert.Equal(result.MasterKey.Value, "!" + hostSecrets.MasterKey);
533533
Assert.Equal(1, Directory.GetFiles(directory.Path, $"host.{ScriptConstants.Snapshot}*").Length);
534534

535535
Assert.True(traceWriter.GetTraces().Any(
@@ -572,9 +572,9 @@ public async Task GetFunctiontSecrets_WhenNonDecryptedSecrets_SavesAndRefreshes(
572572
}
573573

574574
Assert.NotNull(functionSecrets);
575-
Assert.Equal(functionSecrets["Key1"], "cryptoError");
575+
Assert.NotEqual(functionSecrets["Key1"], "cryptoError");
576576
var result = JsonConvert.DeserializeObject<FunctionSecrets>(File.ReadAllText(Path.Combine(directory.Path, functionName + ".json")));
577-
Assert.Equal(result.GetFunctionKey("Key1", functionName).Value, "!cryptoError");
577+
Assert.Equal(result.GetFunctionKey("Key1", functionName).Value, "!" + functionSecrets["Key1"]);
578578
Assert.Equal(1, Directory.GetFiles(directory.Path, $"{functionName}.{ScriptConstants.Snapshot}*").Length);
579579

580580
Assert.True(traceWriter.GetTraces().Any(
@@ -799,7 +799,10 @@ private Mock<IKeyValueConverterFactory> GetConverterFactoryMock(bool simulateWri
799799

800800
var mockValueWriter = new Mock<IKeyValueWriter>();
801801
mockValueWriter.Setup(r => r.WriteValue(It.IsAny<Key>()))
802-
.Returns<Key>(k => new Key(k.Name, simulateWriteConversion ? "!" + k.Value : k.Value) { IsEncrypted = simulateWriteConversion });
802+
.Returns<Key>(k =>
803+
{
804+
return new Key(k.Name, simulateWriteConversion ? "!" + k.Value : k.Value) { IsEncrypted = simulateWriteConversion };
805+
});
803806

804807
var mockValueConverterFactory = new Mock<IKeyValueConverterFactory>();
805808
mockValueConverterFactory.Setup(f => f.GetValueReader(It.IsAny<Key>()))

0 commit comments

Comments
 (0)