Esempio n. 1
0
        public void GetUrl_GeneratesIdentifiableSystemSecret()
        {
            string secretValue = string.Empty;

            var webHookProvider = CreateDefaultScriptWebHookProvider(out Mock <ISecretManager> mockSecretManager, out HostSecretsInfo hostSecrets);

            mockSecretManager.Setup(p => p.GetHostSecretsAsync()).ReturnsAsync(hostSecrets);

            mockSecretManager.Setup(p =>
                                    p.AddOrUpdateFunctionSecretAsync(
                                        "testextension_extension",
                                        It.IsAny <string>(),
                                        HostKeyScopes.SystemKeys,
                                        ScriptSecretsType.Host))
            .Callback <string, string, string, ScriptSecretsType>((key, secret, scope, type) => secretValue = secret)
            .Returns(() => Task.FromResult(new KeyOperationResult(secretValue, OperationResult.Created)));

            // When an extension has no existing secret, one should be generated using
            // the Azure Functions system key seed and standard fixed signature.

            var configProvider = new TestExtensionConfigProvider();
            var url            = webHookProvider.GetUrl(configProvider);

            Assert.Equal($"{TestUrlRoot}{secretValue}", url.ToString());
            Assert.True(IdentifiableSecrets.ValidateBase64Key(secretValue,
                                                              SecretGenerator.SystemKeySeed,
                                                              SecretGenerator.AzureFunctionsSignature,
                                                              encodeForUrl: true));
        }
Esempio n. 2
0
        internal static void ValidateSecret(string secret, ulong seed)
        {
            Assert.True(IdentifiableSecrets.ValidateBase64Key(secret,
                                                              seed,
                                                              SecretGenerator.AzureFunctionsSignature,
                                                              encodeForUrl: true));

            // Strictly speaking, these tests shouldn't be required, failure
            // would indicate a bug in the Microsoft.Security.Utilities API itself
            // Still, this is a new dependency, so we'll do some sanity checking.

            // Azure Function secrets are base64-encoded using a URL friendly character set.
            // These tokens therefore never include the '+' or '/' characters.
            Assert.False(secret.Contains('+'));
            Assert.False(secret.Contains('/'));

            // All Azure function keys are 40 bytes in length, 56 base64-encoded chars.
            Assert.True(secret.Length == 56);
            Assert.True(Base64UrlEncoder.DecodeBytes(secret).Length == 40);

            ulong[] testSeeds = new[]
            {
                uint.MinValue, uint.MaxValue, SecretGenerator.SystemKeySeed,
                SecretGenerator.MasterKeySeed, SecretGenerator.FunctionKeySeed,
            };

            // Verify that validation fails for incorrect seed values.
            foreach (ulong testSeed in testSeeds)
            {
                if (testSeed == seed)
                {
                    // We looked at this one already.
                    continue;
                }

                Assert.False(IdentifiableSecrets.ValidateBase64Key(secret,
                                                                   testSeed,
                                                                   SecretGenerator.AzureFunctionsSignature,
                                                                   encodeForUrl: true));
            }

            // Validate that validation fails for an incorrect signature.
            Assert.False(IdentifiableSecrets.ValidateBase64Key(secret,
                                                               seed,
                                                               "XXXX",
                                                               encodeForUrl: true));
        }